Azure-数据科学助理认证指南-全-

Azure 数据科学助理认证指南(全)

原文:annas-archive.org/md5/41ac68e0c7679ad41531572416d7e2b8

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

本书帮助你获取关于在 Azure 上进行机器学习实验的实际知识。它涵盖了成为认证的 Azure 数据科学家助理所需的所有内容,帮助你理解并掌握相关技能。

本书从数据科学介绍开始,确保你熟悉书中使用的术语。然后,你将进入Azure 机器学习AzureML)工作区,这是你在本书中其余部分的工作环境。你将了解工作室界面,并管理各种组件,如数据存储和计算集群。

接下来,你将专注于无代码和低代码实验。你将探索自动化机器学习向导,它帮助你为数据集定位并部署最佳模型。你还将学习如何使用 AzureML 工作室提供的设计器运行端到端的数据科学实验。

接下来,你将深入探讨以代码为主的数据科学实验。你将探索AzureML 软件开发工具包SDK)用于 Python,并学习如何通过代码创建实验和发布模型。你将学习如何使用强大的计算集群来扩展你的机器学习任务。你将学习如何使用 Hyperdrive 优化模型的超参数。然后,你将学习如何使用负责任的 AI 工具来解释和调试你的模型。一旦你有了训练好的模型,你将学会如何将其用于批量或实时推理,并且了解如何在生产环境中监控它。

通过这些知识,你将对 Azure 机器学习平台有一个清晰的理解,并且能够顺利通过 DP100 考试。

本书适合的读者

本书面向两类读者:希望将 AI 功能融入应用程序的开发人员,以及希望在 Azure 云中扩展其机器学习实验的数据科学家。为了跟上书中的代码示例,你需要具备 Python 的基础知识。对于在 Python 中使用 scikit-learn 等常用框架训练机器学习模型有一定经验的读者,将更容易理解本书内容。

本书的内容

第一章现代数据科学概述,为你提供了全书使用的术语。

第二章部署 Azure 机器学习工作区资源,帮助你理解Azure 机器学习AzureML)工作区的部署选项。

第三章Azure 机器学习工作室组件,提供了你将用于进行数据科学实验的工作室 Web 界面的概述。

第四章配置工作区,帮助你理解如何配置计算资源并连接到托管数据集的数据源。

第五章让机器来做模型训练,引导你进行第一次自动化机器学习AutoML)实验,并通过设计器的向导将最佳训练模型部署为 Web 端点。

第六章可视化模型训练与发布,帮助你通过设计器体验创建训练流水线。你将学会如何通过批处理或实时流水线将训练好的模型投入生产,方法是通过设计器将训练好的流水线提升到生产环境。

第七章AzureML Python SDK,帮助你开始使用代码驱动的数据科学实验。你将了解 AzureML Python SDK 的结构,并学习如何通过代码管理 AzureML 资源,如计算集群。

第八章使用 Python 代码实验,帮助你用代码训练你的第一个机器学习模型。它引导你如何跟踪模型指标,并将你的训练工作扩展到更大的计算集群上。

第九章优化机器学习模型,展示了如何通过超参数调整优化你的机器学习模型,并通过启动自动化机器学习AutoML)实验与代码,帮助你发现适合你数据集的最佳模型。

第十章理解模型结果,向你介绍了负责任的人工智能的概念,并深入探讨了那些能帮助你解读模型预测结果、分析模型常见误差并检测潜在公平性问题的工具。

第十一章与流水线协作,指导你通过定义多步骤流水线,使用 AzureML Python SDK 编写可重复的流程。

第十二章用代码实现模型的生产化,帮助你注册已训练的模型,并通过实时 Web 端点或批处理并行处理流水线实现其生产化。

为了充分利用本书

本书旨在为你提供学习所需的一切。每一章的进一步阅读部分包含一些链接,帮助你深入探讨与本书内容相关的外围话题。如果你对 Azure 门户有一些基本的了解,并且曾阅读过一些 Python 代码,会更有帮助。

本书将引导你使用 AzureML Studio 中的 Notebooks 体验。如果你想在工作站上执行相同的代码,而不是在基于云的环境中执行,你需要一个 Python 环境来运行 Jupyter notebooks。运行 Jupyter notebooks 最简单的方法是通过 VSCode,这是一个免费的跨平台编辑器,具有出色的 Python 支持。你还需要在工作站上安装 Git 来克隆本书的 GitHub 仓库。

如果你正在使用本书的数字版,我们建议你亲自输入代码,或者从本书的 GitHub 仓库访问代码(下一个章节会提供链接)。这样做有助于你避免与复制粘贴代码相关的潜在错误。

如果你在执行代码时遇到问题,请确保你已经从 GitHub 仓库克隆了最新版本。如果问题仍然存在,请随时打开 GitHub 问题页面,描述你遇到的问题,我们将帮助你解决。

下载示例代码文件

你可以从 GitHub 下载本书的示例代码文件,网址为github.com/PacktPublishing/Azure-Data-Scientist-Associate-Certification-Guide。如果代码有更新,它将会在 GitHub 仓库中更新。

我们还提供了其他代码包,来自我们丰富的书籍和视频目录,您可以在github.com/PacktPublishing/查看。

下载彩色图片

我们还提供了一份 PDF 文件,包含本书中使用的截图和图表的彩色版本。你可以在此处下载: static.packt-cdn.com/downloads/9781800565005_ColorImages.pdf

使用的约定

本书中使用了多个文本约定。

文本中的代码:表示文本中的代码词汇、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟网址、用户输入和 Twitter 账号。这里有一个例子:“你也可以更改你正在设计的流水线的自动生成名称。将当前流水线重命名为test-pipeline。”

代码块如下所示:

from azureml.train.hyperdrive import GridParameterSampling
from azureml.train.hyperdrive import choice
param_sampling = GridParameterSampling( {
        "a": choice(0.01, 0.5),
        "b": choice(10, 100)
    }
)

当我们希望特别引起你注意某个代码块时,相关行或项目会以粗体显示:

from azureml.core import Workspace
ws = Workspace.from_config()
loans_ds = ws.datasets['loans']
compute_target = ws.compute_targets['cpu-sm-cluster']

任何命令行输入或输出都以如下方式书写:

az group create --name my-name-rg --location westeurope

粗体:表示一个新术语、一个重要的词汇,或者是你在屏幕上看到的词汇。例如,菜单或对话框中的词汇通常是粗体。这里有一个例子:“导航到 AzureML Studio 网页界面中的 Author | Notebooks 部分。”

提示或重要说明

运行编号在不同的执行中可能会有所不同。每次执行单元时,都会创建一个新的运行编号,从上次的编号继续。因此,如果你执行的代码进行了一次超驱动运行,并且包含 20 个子运行,那么最后一个子运行将是运行 21。下次执行相同代码时,超驱动运行将从运行 22 开始,最后一个子运行将是运行 42。在本节中提到的运行编号是显示在各个图示中的编号,出现差异是正常的,特别是当你需要重新执行几个单元时。

联系我们

我们欢迎读者的反馈。

一般反馈:如果你对本书的任何内容有疑问,请通过电子邮件联系我们,邮箱地址是 customercare@packtpub.com,并在邮件主题中注明书名。

勘误:尽管我们已尽一切努力确保内容的准确性,但难免会有错误。如果你发现本书中的错误,感谢你向我们报告。请访问www.packtpub.com/support/errata并填写表格。

盗版:如果你在互联网上发现任何我们作品的非法复制品,感谢你提供该位置地址或网站名称。请通过电子邮件联系 copyright@packt.com,并附上该材料的链接。

如果你有兴趣成为作者:如果你在某个领域有专长,并且有兴趣撰写或参与编写一本书,请访问authors.packtpub.com

分享你的想法

一旦你阅读了《Azure 数据科学家助理认证指南》,我们很想听听你的想法!请点击这里直接进入亚马逊书籍评论页面并分享你的反馈。

你的评论对我们以及技术社区非常重要,它将帮助我们确保提供优质的内容。

第一部分:开始你的云端数据科学之旅

Azure 数据科学家助理是具有应用数据科学和机器学习知识的领域专家,能够在 Azure 上运行机器学习工作负载。此角色的责任包括为 Azure 上的数据科学工作负载规划和创建合适的工作环境。在本节中,你将获得本书中使用的所有数据科学和机器学习术语的概览。你还将学习如何配置和设置 Azure 机器学习服务,这一环境是运行 Azure 云中的机器学习实验的事实标准。

本节包括以下章节:

  • 第一章, 现代数据科学概览

  • 第二章, 部署 Azure 机器学习工作区资源

  • 第三章, Azure 机器学习工作室组件

  • 第四章, 配置工作区

第一章:第一章:现代数据科学概述

数据科学起源于 18 世纪初,并在过去几十年里获得了巨大的流行。

在本书中,你将学习如何在 Azure 上运行数据科学项目,Azure 是微软的公共云基础设施。你将掌握成为认证 Azure 数据科学家助理所需的所有技能。你将从本章开始,了解书中贯穿的基础术语。然后,你将深入学习Azure 机器学习AzureML)服务。你将首先配置工作区,然后在 AzureML Studio 网页界面中体验无代码、低代码的构建。接着,你将深入学习以代码为主的数据科学实验,使用 AzureML 软件开发工具包SDK)进行工作。

在本章中,你将学习一些与数据科学相关的基本术语,这些术语是 DP 100 考试所需的。你将从了解数据科学项目的典型生命周期开始。接着,你将阅读有关大数据的内容,并了解 Apache Spark 技术如何帮助你训练机器学习模型。然后,你将探索什么是DevOps思维方式,以及它如何帮助你成为一个高效、多学科、敏捷团队的成员,这个团队构建了增强机器学习的产品。

在本章中,我们将涵盖以下主要内容:

  • 数据科学的演变

  • 进行数据科学项目

  • 在数据科学中使用 Spark

  • 采纳 DevOps 思维方式

数据科学的演变

如果你试图追溯数据科学实践的根源,你可能会发现它的证据可以追溯到文明的初期。18 世纪,政府开始收集人口和财务数据用于征税,这一做法被称为统计学。随着时间的推移,这个术语的使用范围扩展到包括对收集的数据进行总结和分析。1805 年,法国数学家阿德里安-玛丽·勒让德发布了一篇论文,描述了用最小二乘法拟合线性方程,尽管大多数人将对该方法的完整描述归功于卡尔·弗里德里希·高斯,他在几年后发表了相关内容。1900 年,卡尔·皮尔逊在《哲学杂志》上发布了关于卡方统计量的观察,这是数据科学中假设检验的基石。1962 年,因快速傅里叶变换箱型图而闻名的科学家约翰·图基,发表了一篇论文,表达了他对数据分析的热情,以及统计学如何需要演变成一门新的科学。

另一方面,随着二十世纪中叶信息学的兴起,人工智能AI)领域由约翰·麦卡锡(John McCarthy)于 1955 年首次提出,作为思考机器的官方术语。人工智能是计算机科学的一个领域,旨在开发可以模仿人类智能行为的系统。使用诸如信息处理语言IPL)和列表处理器LISP)等编程语言,开发人员编写了能够操纵列表和其他各种数据结构以解决复杂问题的程序。在 1955 年,阿瑟·塞缪尔(Arthur Samuel)的跳棋程序是第一款能够通过存储棋盘状态并缓存在该状态下获胜的几率来从已经进行过的游戏中学习的程序。这个跳棋程序可能是机器学习(人工智能的一个子领域)的第一个例子,机器学习利用历史数据和数据中编码的模式来训练模型,使系统能够模仿人类任务,而无需显式编写整个逻辑。事实上,你可以将机器学习模型看作是通过对数据集训练算法以识别特定类型模式所生成的软件代码。

2001 年,威廉·S·克利夫兰(William S. Cleveland)发表了第一篇文章,其中使用了“数据科学”这一术语,这一术语至今仍被我们沿用,指的是处于统计学、数据分析和信息学交叉点的科学,旨在通过数据解释现象。

尽管大多数人将数据科学与机器学习相关联,但数据科学的范围要广泛得多,它包括在实际机器学习模型训练过程之前的数据分析和准备工作,正如你将在下一节中看到的那样。

从事数据科学项目

数据科学项目的目标是将从数据中提取的智能融入应用程序中。在本节中,你将发现该类项目中所需的常见任务和关键考虑事项。有许多成熟的生命周期过程,例如团队数据科学过程TDSP)和跨行业标准数据挖掘过程CRISP-DM),它们描述了在典型项目中执行的迭代阶段。最常见的阶段如图 1.1所示:

图 1.1 – 数据科学项目的迭代阶段

图 1.1 – 数据科学项目的迭代阶段

尽管图表展示了各阶段之间的某些指示性流动,但如果需要,你可以自由地从一个阶段跳转到任何其他阶段。此外,这种方法是迭代的,数据科学团队应当经过多次迭代,不断改进其业务理解和最终模型,直到满足成功标准。在本章的采用 DevOps 思维模式部分,你将进一步了解迭代过程的好处。数据科学过程从业务理解阶段开始,这是你将在下一节中详细阅读的内容。

了解业务问题

数据科学项目的第一阶段是业务理解阶段。在这个阶段,数据科学团队与业务利益相关者合作,定义一个简短而直接的问题,机器学习将尝试回答。

图 1.2 显示了机器学习可以回答的五个最常见问题:

图 1.2 – 机器学习可以回答的五个问题

图 1.2 – 机器学习可以回答的五个问题

在这些问题背后,有一组建模技术你将使用:

  • 回归模型允许你基于一个或多个特征预测一个数值。例如,在第八章《用 Python 代码进行实验》中,你将尝试基于一年之前采集的 10 个测量值,预测你希望获得的数值。训练一个回归模型是一个监督式的机器学习任务,这意味着你需要提供足够的样本数据来训练模型,以预测期望的数值。

  • 分类模型允许你根据一组输入预测一个类标签。这个标签可以是简单的“是/否”标签,也可以是蓝色、绿色或红色等颜色标签。例如,在第五章《让机器进行模型训练》中,你将训练一个分类模型,检测客户是否会取消他们的手机订阅。预测一个人是否会停止做某件事,通常被称为流失或退订检测。训练一个分类模型是一个监督式机器学习任务,需要一个带标签的数据集来训练模型。带标签的数据集包含了输入和你希望模型预测的标签。

  • 聚类是一个无监督的机器学习任务,用于对数据进行分组。与前两种模型类型不同,聚类不需要任何训练数据。它直接作用于给定的数据集,并创建所需数量的集群,将每个数据点分配到相应的集群中。聚类模型的常见应用是当你试图识别你客户基础中的不同消费群体,以便你可以通过特定的营销活动来针对这些群体。

  • 推荐系统旨在基于用户的个人资料推荐最佳选项。搜索引擎、电子商店和流行的视频流媒体平台利用这种类型的模型来提供个性化的推荐,帮助用户决定接下来该做什么。

  • 异常检测模型可以从数据集或数据流中检测异常值。异常值是指那些与其他元素不相符的项目,表示存在异常。例如,如果一台机器的振动传感器开始发送异常测量值,这可能是设备即将故障的良好指示。

在业务理解阶段,你将尝试理解问题陈述并定义成功标准。设定机器学习能够和不能做到的适当预期是确保团队之间一致性的关键。

在数据科学项目中,通常会有多轮的业务理解。数据科学团队在探索数据集或训练模型后会获得很多洞察。将这些洞察带给业务利益相关者,验证你团队的假设,或深入了解你正在解决的问题是非常有帮助的。例如,业务利益相关者可能会解释你在数据中检测到的模式,但你却无法解释其背后的原因。

一旦你掌握了要解决的问题,接下来你需要获取一些数据,进行探索,甚至为其打上标签,更多内容将在下一节中讲解。

获取和探索数据

在理解了你要解决的问题后,接下来是收集支持机器学习过程的数据。数据可以有多种形式和格式。它既可以是存储在数据库系统中的结构化表格数据,也可以是存储在文件共享中的文件,如图像等。起初,你可能不知道要收集哪些数据,但你必须从某个地方开始。寻找数据时,一个典型的轶事是,总觉得总有一个 Excel 文件包含了关键信息,你必须不断地去请求,直到找到它。

一旦你找到了数据,你就需要分析它,了解数据集是否完整。数据通常存储在本地系统中,或者存储在在线事务处理OLTP)数据库中,你无法轻易访问。即使数据可以访问,也不建议直接在源系统中探索它,因为你可能会意外影响承载数据的底层引擎的性能。例如,针对销售表的复杂查询可能会影响电子商店解决方案的性能。在这种情况下,通常会将所需的数据集导出为某种文件格式,比如最具互操作性的逗号分隔值CSV)格式,或者更加优化用于分析处理的Parquet格式。然后将这些文件上传到便宜的云存储中,供进一步分析使用。

在 Microsoft Azure 中,最常见的目标要么是存储帐户中的 Blob 容器,要么是 Azure Data Lake Gen 2 文件系统中的文件夹,它提供了更加细粒度的访问控制机制。数据复制可以通过使用如 AzCopyStorage Explorer 等工具以一次性方式进行。如果你想要配置一个可以定期拉取增量新数据的重复过程,你可以使用更高级的工具,如 Azure Data FactoryAzure Synapse Analytics 的管道。在 第四章中,配置工作区,你将回顾从本地提取数据所需的组件以及你可以从 AzureML 工作区中连接的可用数据存储,以便访问各种数据集。在 第四章与数据集一起工作 部分,你将了解 AzureML 支持的数据集类型,以及如何探索它们以深入了解其中存储的信息。

收集数据时,一个常见的任务是数据清理步骤。在这个过程中,你需要删除重复记录、填补缺失值或修复常见的数据输入问题。例如,你可以通过将 UK 记录替换为 United Kingdom 来统一国家文本字段。在 AzureML 中,你可以在 第六章 中看到的设计器中,或通过你将从 第七章 起使用的笔记本体验来执行这些清理操作。尽管你可能会在 AzureML 中开始进行这些清理操作,但随着项目的推进,这些清理活动通常会移到 Azure Data FactoryAzure Synapse Analytics 的管道中,这些管道将数据从源系统中提取出来。

重要提示

在进行数据清理时,要注意 yak shaving。术语 yak shaving 在 90 年代被创造出来,用来描述一种情形:在处理某项任务时,你意识到必须做另一个任务,这又引发了另一个任务,以此类推。这一系列任务可能会让你偏离原定目标。例如,你可能会发现一些记录在国家文本字段中存在无效编码,但你可以理解参考的国家。于是你决定更改 CSV 文件的导出编码,但你意识到你使用的导出工具已经过时,不支持 UTF-8。这时你开始寻找系统管理员来更新你的软件。与其沿着这个方向走,不如记下需要做的事情,并将其添加到待办事项中。你可以在下次迭代时修复这个问题,那时你会更清楚自己是否真的需要这个字段。

另一个常见的任务是对数据集进行标注,特别是当您需要处理监督学习模型时。例如,如果您正在整理一个数据集来预测客户是否会流失,您需要标记取消订阅的客户记录。一个更复杂的标注案例是当您为社交媒体消息创建情感分析模型时。在这种情况下,您需要获取一批消息,逐一浏览,并为每条消息标记其情感是正面还是负面。

在 AzureML Studio 中,您可以创建标注项目,允许您对数据集的标注工作进行扩展。AzureML 允许您定义文本标注或图像标注任务。然后,您可以邀请团队成员根据给定的指示来标注数据。一旦团队开始标注数据,AzureML 会自动训练一个相应的模型。当模型足够好时,它开始向标注者提供建议,从而提高生产力。图 1.3 显示了标注项目创建向导以及当前图像标注任务中的各种选项:

图 1.3 – 创建 AzureML 标注项目

图 1.3 – 创建 AzureML 标注项目

通过此项目阶段,您应已发现相关的源系统,并生成了一个准备好用于机器学习训练的清理数据集。在下一部分,您将学习如何创建其他数据特征,帮助模型训练过程,这一过程称为 特征工程

特征工程

在特征工程阶段,您将生成新的数据特征,以更好地表示您要解决的问题,并帮助机器从数据集中学习。例如,以下代码块通过转换销售数据集中的 product 列创建一个名为 product_id 的新特征:

product_map = { "orange juice": 1, "lemonade juice": 2 }
dataset["product_id"] = dataset["product"].map(product_map)

该代码块使用 map 方法将文本转换为数值。product 列被称为 橙汁柠檬水。如果您在同一数据集中有一个 1 到 5 的评级特征,那将是一个离散的数值变量,能够取的值是有限的,在本例中只有 12345。如果您有一个记录客户购买了多少升或多少加仑的列,那么它将是一个 连续 数值变量,可以取任何大于或等于零的数值,例如半升。除了数值,日期字段也被视为连续变量。

重要提示

尽管在前面的示例中,product_id 特征是一个 离散 数值变量,但这类特征通常被当作分类变量来处理,正如您将在 第五章《让机器来进行模型训练》中看到的那样。

有许多可用的特征化技术。以下是一个示例列表:

  • 数值特征的标准化:此技术将所有数值特征转换为可以轻松比较的范围。例如,在第八章使用 Python 代码进行实验中,你将基于医学测量数据训练机器学习模型。血糖测量值范围从 80 到 200 mg/dL,而血压测量值范围从 60 到 128 mm Hg。这些数值通过它们的均值进行标准化,这种转换称为标准化或Z-score归一化。它们的数值最终会在 -1 到 1 的范围内,这样机器就能提取出更好的洞察。

  • 拆分:将一列拆分为两个新特征是非常常见的做法。例如,全名会被拆分为姓名和姓氏以便进一步分析。

  • 分箱:此技术将连续特征分组为不同的组或箱,这可能揭示出有关你正在解决的问题的重要信息。例如,如果你有出生年份数据,可以创建分箱来将不同的代际群体分组。在这种情况下,出生年份在 1965 到 1980 年之间的人将属于X 代群体,而出生在 1981 到 1996 年间的人则属于千禧一代分组。通常会使用你在理解商业问题部分中看到的聚类模型来生成群体并定义这些分箱。

  • 对于 product,你执行了标签编码。你将类别变量转换为数值变量。标签编码的一个典型例子是 T 恤尺码,其中小号对应1,中号对应2,大号对应3。然而,在 product 例子中,你不小心定义了 橙汁1)和 柠檬汁2)之间的顺序,这可能会让机器学习算法感到困惑。在这种情况下,除了使用示例中产生 product_id 特征的顺序编码,你还可以使用独热编码。在这种情况下,你将引入两个二进制特征,分别为orange_juicelemonade_juice。这些特征将根据顾客购买的是哪种果汁,接受01的值。

  • 生成滞后特征:如果你处理的是时间序列数据,可能需要从前一个时间点的值生成特征。例如,如果你尝试预测 10 分钟后的温度,你可能需要当前的温度以及 30 分钟前和 1 小时前的温度。这两个额外的过去温度就是滞后特征,你需要对它们进行特征工程。

    重要提示

    对大数据集进行所有这些转换可能需要大量的内存和处理时间。这时,像 Spark 这样的技术就发挥了作用,通过并行化处理过程。你将在本章的使用 Spark 进行数据科学部分了解更多关于 Spark 的内容。

第十章中,理解模型结果部分,你将使用来自sklearn库的MinMaxScaler方法对数值特征进行缩放。

作为特征工程阶段的最后一步,你通常会移除不必要或高度相关的特征,这个过程称为特征选择。你将删除那些不会用于训练机器学习模型的列。通过删除这些列,你减少了训练时机器的内存需求,减少了训练模型所需的计算时间,同时生成的模型体积也会更小。

在创建这些特征时,你可能需要返回到数据获取和探索阶段,甚至回到理解业务问题阶段,以获取更多的数据和见解。然而,某一时刻,你的训练数据集将准备好训练模型,这将在下一节中介绍。

训练模型

一旦你准备好数据集,机器学习的训练过程就可以开始。如果模型需要监督学习且你有足够的数据,你可以将数据集按 70%对 30%或 80%对 20%的比例分为训练集和验证集。你选择要训练的模型类型,指定模型的训练参数(称为超参数),并训练模型。使用剩余的验证数据集,你根据指标评估训练模型的性能,并决定该模型是否足够好,可以进入下一个阶段,或者是否需要返回到理解业务问题阶段。监督模型的训练过程如图 1.4所示:

图 1.4 – 训练一个监督学习模型

](https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/az-ds-ass-cert-gd/img/B16777_01_004.jpg)

图 1.4 – 训练一个监督学习模型

上述步骤有几种变体:

  • 如果模型属于无监督学习类别,例如聚类算法,你只需将所有数据传入训练模型。然后评估检测到的聚类是否满足业务需求,调整超参数,再次尝试。

  • 如果你有一个需要监督学习的模型,但没有足够的数据,通常使用k 折交叉验证技术。通过 k 折交叉验证,你可以指定要将数据集拆分成的折数。AzureML 使用AutoML,如果数据少于 1,000 行,则执行 10 折验证;如果数据集在 1,000 到 20,000 行之间,则执行 3 折验证。一旦你有了这些折,你就开始一个迭代过程,具体步骤如下:

    1. 保留一个折用于验证,并使用其余的折来训练一个新的模型。

    2. 使用保留的折对训练的模型进行评估。

    3. 记录模型得分并丢弃模型。

    4. 重复步骤 I,将另一个折保留用于验证,直到所有折都用于验证。

    5. 生成聚合模型的性能。

      重要提示

      在机器学习研究文献中,有一种方法叫做半监督学习。这种方法将少量标记数据与大量未标记数据结合起来训练模型。

与其训练一个单一的模型,评估结果后再尝试使用不同的超参数集,你可以自动化这个过程,并行评估多个模型。这个过程叫做超参数调优,你将在第九章优化机器学习模型中深入了解。在同一章中,你还将学习如何自动化模型选择,这是一种 AzureML 的功能,称为 AutoML。

度量标准帮助你选择使预测值与实际值之间差异最小的模型。它们因训练的模型类型而有所不同。在回归模型中,度量标准试图最小化预测值与实际值之间的误差。最常见的度量标准有平均绝对误差MAE)、均方根误差RMSE)、相对平方误差RSE)、相对绝对误差RAE)、决定系数)和归一化均方根误差NRMSE),这些你将在第八章使用 Python 代码进行实验中看到。

在分类模型中,度量标准略有不同,因为它们不仅要评估模型正确预测的结果数量,还要评估错误分类的数量。例如,在客户流失的二分类问题中,可能有四种结果:

  • 模型预测客户会流失,且客户确实流失了。这被认为是真阳性TP)。

  • 模型预测客户会流失,但客户保持忠诚。这被认为是假阳性FP),因为模型错误地预测了客户会流失。

  • 模型预测客户不会流失,但客户流失了。这被认为是假阴性FN),因为模型错误地判断了客户会忠诚。

  • 模型预测客户不会流失,且客户保持忠诚。这被认为是真阴性TN)。

这四种情况构成了混淆矩阵,如图 1.5所示:

图 1.5 – 分类模型的评估

图 1.5 – 分类模型的评估

通过混淆矩阵,你可以计算其他指标,例如准确率,它计算评估测试中所有正确结果的总数(在此案例中,1132 TP + 2708 TN = 3840 条记录与 2708 + 651 + 2229 + 1132 = 6720 条总记录)。另一方面,精确度阳性预测值 (PPV) 评估实际正确的预测有多少(在此案例中,1132 TP 与 1132 + 2229 总的正确预测)。召回率,也称为敏感性,衡量有多少实际的真实值被正确分类(在此案例中,1132 TP 与 1132 + 651 总的实际真实值)。根据你要解决的业务问题,你需要在各种指标之间找到平衡,因为某些指标可能比其他指标更有帮助。例如,在 COVID-19 大流行期间,一个模型如果通过召回率为 1 来确定某人是否感染了病毒,会识别出所有感染的患者。然而,它也可能错误地分类了一些未感染的患者,而其他指标,如精确度,则能够捕捉到这一点。

重要提示

当你的模型过于拟合数据时,请留意。这是我们所说的过拟合,它可能表示模型在训练数据集中找到了某种在现实生活中不存在的模式。此类模型在投入生产并对未知数据进行推理时,往往表现不佳。过拟合的常见原因是偏倚的训练数据集,它仅暴露了真实世界样本的一部分。另一个原因是目标泄露,即某种方式下,试图预测的值被作为输入传递给模型,可能是通过一个使用目标列工程化的特征。有关如何处理过拟合和不平衡数据的指导,请参阅进一步阅读部分。

正如你迄今所见,训练机器学习模型时需要考虑许多因素,在本书中,你将获得一些训练模型的实战经验。在大多数情况下,你首先需要选择将要执行训练过程的计算机类型。目前,你有两个选择,中央处理单元CPU)或图形处理单元GPU)计算目标。这两种目标至少都包含一个 CPU,因为这是任何现代计算机的核心元素。不同之处在于,GPU 计算目标还提供一些非常强大的显卡,可以执行大规模的并行数据处理,从而加速训练过程。为了利用 GPU,你训练的模型需要支持基于 GPU 的训练。GPU 通常用于神经网络训练,使用的框架包括TensorFlowPyTorchKeras

一旦你训练了一个满足在数据科学项目的理解业务问题阶段定义的成功标准的机器学习模型,就该将其操作化,并开始使用它进行推理了。你将在下一节阅读到这一部分内容。

部署模型

在模型操作化方面,你有两种主要方法:

  • 实时推理:模型始终处于加载状态,等待对传入数据进行推理。典型的使用场景是网页和移动应用程序,这些应用会调用模型来根据用户输入进行预测。

  • 批处理推理:每次调用批处理过程时,都会加载模型,并基于传入的批记录生成预测。例如,假设你训练了一个模型来识别照片中的你的面部,并且你想要为硬盘上的所有图片打上标签。你将配置一个过程,使用模型对每张图片进行处理,并将结果存储在文本或 CSV 文件中。

这两者之间的主要区别在于你是否已经拥有用于预测的数据。如果你已经拥有数据且这些数据不发生变化,你可以进行批处理推理。例如,如果你想预测下周比赛的足球比分,你可以运行批处理推理并将结果存储在数据库中。当客户请求特定的预测时,你可以从数据库中提取结果。然而,在足球比赛进行时,预测最终比分的模型需要实时获取诸如当前球员数量和受伤情况等特征信息。对于这些情况,你可能想要部署一个暴露 REST API 的 Web 服务,在该服务中,你发送所需的信息,模型则进行实时推理。你将在第十二章通过代码操作化模型中深入了解实时和批处理方法。

在这一部分,你回顾了数据科学项目的生命周期,并逐步了解了所有阶段,从理解需要做什么到通过部署批处理或实时服务来实现模型操作化。特别是在实时流处理中,你可能听说过结构化流处理这一术语,它是基于 Spark 构建的一个可扩展的处理引擎,允许开发者像在静态数据上执行批处理推理一样执行实时推理。你将在下一节学习更多关于 Spark 的内容。

在数据科学中使用 Spark

在 21 世纪初,大数据问题成为现实。数据中心存储的数据在数量和速度上迅速增长。到 2021 年,我们将数据集称为大数据,当它们的大小达到至少几个 TB 时,甚至在大型组织中,PB 级的数据也并不罕见。这些数据集以非常快的速度增长,可能是每天几 GB,甚至是每分钟增长的速度,例如,当你在在线商店中存储用户与网站的交互数据以进行点击流分析时。

2009 年,加利福尼亚大学伯克利分校启动了一个研究项目,旨在提供处理大数据所需的并行计算工具。2014 年,Apache Spark 的第一个版本从该研究项目中发布。该研究团队的成员创办了Databricks公司,这是 Apache Spark 开源项目的重要贡献者之一。

Apache Spark 提供了一个易于使用的可扩展解决方案,允许人们以分布式的方式对数据进行并行处理。Spark 架构的核心思想是,驱动节点负责执行你的代码。你的代码被拆分成多个可以在更小数据部分上执行的并行任务。这些小任务会被调度到工作节点执行,如图 1.6所示:

图 1.6 – 在 Spark 集群中并行处理大数据

图 1.6 – 在 Spark 集群中并行处理大数据

例如,假设你想计算公司在去年销售了多少产品。在这种情况下,Spark 可以启动 12 个任务,分别生成每月的汇总数据,然后这些结果将由另一个任务处理,汇总所有月份的总数。如果你倾向于将整个数据集加载到内存中并直接进行汇总,我们来看看你需要多少内存。假设单月的销售数据存储在一个 1GB 的 CSV 文件中。加载这个文件大约需要 10GB 的内存。压缩后的pandas.``DataFrame对象。正如你能理解的那样,同时加载所有 12 个文件到内存中是一个不可能完成的任务。你需要并行处理,而 Spark 可以自动为你完成这个工作。

重要提示

Parquet 文件以列式格式存储,这使得你可以仅加载需要的部分列。例如,在 1GB 的 Parquet 文件中,如果你只加载数据集的一半列,那么你可能只需要 20GB 的内存。这也是 Parquet 格式在分析负载中广泛使用的原因之一。

Spark 是用 Scala 编程语言编写的。它为 Scala、Python、Java、R,甚至 C# 提供了 API。不过,数据科学社区通常在使用 Scala 时,致力于达到最大计算性能并利用 Java 库生态系统,或者使用 Python,这也是现代数据科学社区广泛采用的语言。当你编写 Python 代码来利用 Spark 引擎时,你是在使用 PySpark 工具对后来在 Spark 框架中引入的Spark.DataFrame对象进行操作。为了从 Spark 的分布式特性中获益,你需要处理大量数据集。这意味着,如果你处理的记录仅为几十万条甚至几百万条,Spark 可能会显得过于复杂。

Spark 提供了两个机器学习库,旧的Spark.DataFrame结构,这是一个分布式数据集合,并提供与 Python pandas 或 R 中使用的DataFrame对象类似的功能。此外,pandas.DataFrame的操作允许你利用现有的编码技能在 Spark 上进行操作。

AzureML 允许你在 PySpark 上执行 Spark 任务,既可以使用其原生计算集群,也可以通过连接到Azure DatabricksSynapse Spark 池来实现。尽管本书中你不会编写任何 PySpark 代码,但在 第十二章,《使用代码实现模型操作》中,你将学习如何在不需要 Spark 或驱动节点的情况下实现类似的并行化效果。

无论你是在普通的 Python、PySpark、R 还是 Scala 中编程,你都在生成一些代码工件,这些代码很可能是更大系统的一部分。在下一部分,你将探索 DevOps 思维模式,该模式强调软件工程师、数据科学家和系统管理员之间的沟通与协作,以实现更快的有价值产品特性的发布。

采纳 DevOps 思维模式

DevOps 是一种团队思维模式,旨在尽量减少开发人员和系统操作员之间的隔阂,从而缩短产品的开发生命周期。开发人员不断修改产品以引入新特性和修改现有行为。另一方面,系统操作员需要保持生产系统的稳定并确保其正常运行。在过去,这两个团队是孤立的,开发人员常常是将新的软件部分“抛”给运营团队,后者会尝试将其部署到生产环境中。正如你所想,事情并不总是那么顺利,导致这两个团队之间出现摩擦。说到 DevOps,一个基本的实践是,团队需要具备自主性,并应包含所有所需的学科,包括开发人员操作员

在数据科学领域,一些人将这项实践称为MLOps,但其基本理念保持不变。一个团队应该是自给自足的,能够开发出整体解决方案所需的所有组件,从带入数据的数据工程部分、模型的训练,一直到在生产环境中运营化模型。这些团队通常以敏捷的方式工作,采用迭代方法,根据反馈寻求持续改进,正如图 1.7所示:

图 1.7 – 敏捷 MLOps 团队中的反馈流程

图 1.7 – 敏捷 MLOps 团队中的反馈流程

MLOps 团队根据其待办事项执行迭代步骤,正如你在数据科学项目工作部分看到的那样。一旦模型准备好,作为团队一部分的系统管理员会知道需要做些什么来将模型投入生产。模型被密切监控,如果发现缺陷或性能下降,则为 MLOps 团队创建一个待办事项,安排在下一个冲刺中处理。

为了最小化生产中新增特性的开发和部署生命周期,需要拥抱自动化。DevOps 团队的目标是尽量减少部署过程中人工干预的次数,并自动化尽可能多的可重复任务。

图 1.8显示了使用 MLOps 思维方式开发实时模型时最常用的组件:

图 1.8 – MLOps 驱动的数据科学项目中常见的组件

图 1.8 – MLOps 驱动的数据科学项目中常见的组件

让我们分析这些组件:

  • ARM 模板允许你自动化 Azure 资源的部署。这使得团队可以快速启动和关闭开发、测试,甚至生产环境。这些构件存储在 Azure DevOps 的 Git 版本控制仓库中。通过 Azure DevOps 管道,多个环境的部署得以自动化。你将会在第二章中阅读关于 ARM 模板的内容,部署 Azure 机器学习工作区资源

  • 使用Azure Data Factory,数据科学团队协调从源系统提取和清洗数据。数据被复制到数据湖中,可以从 AzureML 工作区访问。Azure Data Factory 使用 ARM 模板定义其协调管道,这些模板存储在 Git 仓库中,以便跟踪变更并能够在多个环境中部署。

  • 在 AzureML 工作区内,数据科学家正在编写他们的代码。最初,他们开始使用 Jupyter 笔记本。笔记本是一个很好的原型设计工具,正如你在第七章,《AzureML Python SDK》中所看到的那样。随着项目的进展,脚本会从笔记本中导出,并整理成编码脚本。所有这些代码制品都会通过 Git 进行版本控制,使用终端和如图 1.9所示的命令:

图 1.9 – 在 AzureML 中使用 Git 对笔记本和脚本文件进行版本控制

图 1.9 – 在 AzureML 中使用 Git 对笔记本和脚本文件进行版本控制

  • 当一个模型经过训练后,如果其性能优于当前生产环境中的模型,它会在 AzureML 中注册,并触发一个事件。这个事件会被 AzureML DevOps 插件捕获,从而触发模型在测试环境中的自动部署。模型会在该环境中进行测试,如果所有测试通过且在Application Insights中未记录任何错误(该工具用于监控部署),则可以将制品自动部署到下一个环境,直到生产环境。

确保代码和模型质量的能力在这个自动化过程中起着至关重要的作用。在 Python 中,你可以使用各种工具,如 Flake8、Bandit 和 Black,来确保代码质量、检查常见的安全问题,并保持代码库的一致格式。你还可以使用pytest框架编写功能测试,在这些测试中,你将把模型的结果与黄金数据集进行对比。通过pytest,你甚至可以执行集成测试,验证端到端系统是否按预期工作。

采用 DevOps 是一项永无止境的旅程。每次重复这个过程,团队都会变得更好。诀窍在于建立对端到端开发和部署过程的信任,让每个人都能自信地做出更改并将其部署到生产环境。当过程失败时,要理解失败的原因,并从错误中吸取教训。创建防止未来失败的机制,并继续前行。

总结

在本章中,您了解了数据科学的起源以及它与机器学习的关系。然后,您学习了数据科学项目的迭代性质,并发现了您将要进行的各个阶段。从问题理解阶段开始,您将获取和探索数据,创建新特征,训练模型,然后进行部署以验证您的假设。接着,您看到如何使用 Spark 生态系统扩展大数据文件的处理。在最后一节中,您了解了 DevOps 思维方式,它帮助敏捷团队提高效率,即在短时间内开发和部署新产品功能。您看到 MLOps 驱动的团队中常用的组件,并看到在该图的中心位置,您会找到 AzureML。

在下一章中,您将学习如何部署 AzureML 工作区,并了解在本书中整个数据科学之旅中将使用的 Azure 资源。

深入阅读

本节提供了一些有用的网络资源,帮助您扩展对本章中涉及的主题的理解:

第二章:第二章:部署 Azure 机器学习工作区资源

在本章中,你将学习如何通过 Azure 门户和 命令行界面CLI)部署 Azure 机器学习Azure ML)工作区。你还将了解在部署工作区时需要选择的部署参数。最后,你将拥有一个完全功能的 Azure ML 工作区,并能够访问所有已部署的 Azure 资源。

在本章中,我们将涵盖以下主要内容:

  • 通过门户部署 Azure ML

  • 通过 CLI 部署 Azure ML

  • 部署 Azure ML 工作区的替代方式

  • 探索已部署的 Azure 资源

技术要求

要创建 Azure ML 工作区,你需要一个 Azure 订阅。你可以通过访问 azure.microsoft.com/free/ 获得免费试用。如果你想使用现有的订阅,你需要请求订阅所有者提供以下 资源组 项目:

  • packt-azureml-rg

  • packt-azureml-cli-rg

本书假设你在这些资源组中拥有 Contributor 角色或 Owner 角色。你将通过 Azure 门户和 Azure CLI 在这两个资源组中各部署一个 Azure ML 工作区。

Azure ML 需要在托管资源组的 Azure 订阅中注册以下提供程序:

  • Microsoft.MachineLearningServices

  • Microsoft.KeyVault

  • Microsoft.Storage

  • Microsoft.insights

  • Microsoft.ContainerRegistry

  • Microsoft.Notebooks

如果你是订阅的 Owner,Azure 会在你部署资源时自动为你注册提供程序。否则,你需要按照 docs.microsoft.com/azure/azure-resource-manager/templates/error-register-resource-provider#solution-3---azure-portal 上的说明请求订阅所有者为你注册这些提供程序。

你需要一个启用了 JavaScript 的现代浏览器。访问 Azure 门户时需要此功能。

可选地,你可以从微软官方文档页面 docs.microsoft.com/cli/azure/install-azure-cli 下载并安装 Azure CLI。本书将教你如何使用嵌入在 Azure 门户中的在线版本。

你可以在 GitHub 上找到本章的所有命令和代码片段:bit.ly/dp100-ch02

通过门户部署 Azure ML

在本节中,你将通过 Azure 门户向导部署一个 Azure ML 工作区。首先,导航到 Azure 门户 portal.azure.com

有几种方法可以启动 Azure ML 工作区向导的创建。以下是三种最常见的方法:

  • 从 Azure 门户的主页,您可以从页面顶部的 Azure 服务 标签下或左上角的 Azure 门户菜单 中选择 创建资源

图 2.1 – 在 Azure 门户中创建资源

图 2.1 – 在 Azure 门户中创建资源

这种方法是最通用的,会要求您搜索要创建的服务。搜索 machine learning 并选择 Microsoft 提供的 Marketplace 搜索结果中的第一个选项:

图 2.2 – Azure Marketplace 中的 ML 搜索结果

图 2.2 – Azure Marketplace 中的 ML 搜索结果

您可以查看服务信息。完成后,点击 创建 按钮启动向导。

  • 或者,您可以在 Azure 门户的顶部搜索栏中搜索 machine learning,并选择 Machine Learning 选项,该选项出现在 服务 下:

图 2.3 – 在 Azure 门户中显示的 ML 服务搜索结果

图 2.3 – 在 Azure 门户中显示的 ML 服务搜索结果

这将引导您进入您可以访问的已经部署的 ML 工作区列表。如果这是一个新的订阅,则该列表为空;您可以点击工具栏中的 添加 按钮:

图 2.4 – 空服务列表中可用的创建按钮

图 2.4 – 空服务列表中可用的创建按钮

  • 最常见的方法是导航到您希望部署 Azure ML 工作区的资源组,并从工具栏中选择 添加

图 2.5 – 资源组中的添加选项

图 2.5 – 资源组中的添加选项

搜索 machine learning,并选择 Microsoft 提供的 Marketplace 搜索结果中的第一个选项。点击 创建 按钮以启动向导。此方法将自动填充向导中的资源组选项。

这三种方法都将引导您进入部署向导:

图 2.6 – ML 工作区创建向导

图 2.6 – ML 工作区创建向导

在下一部分,您将学习如何使用向导来部署 Azure ML 工作区。

使用部署向导

向导包括五个步骤或选项卡:

  1. 基础信息:这是关于您即将部署的工作区的基本信息。

  2. 网络设置:这是指您可能希望配置的高级网络选项。

  3. 高级设置:这包括高级身份验证和数据安全工作区选项

  4. 标签:这包括工作区中的相关标签

  5. 审核 + 创建:这是向导的最后一步;经过简短的验证过程后,您可以部署工作区。

    在接下来的章节中,我们将回顾向导中所有可用的选项,并讨论在选择它们之前需要考虑的事项。

    重要提示

    如果你在向导的基本步骤中看到警告选定的订阅没有权限注册资源提供者,请确保向 Azure 订阅的所有者请求注册本章技术要求部分提到的资源提供者(如果缺少提供者)。如果这些提供者没有注册,将导致在向导的审查 + 创建步骤中出现验证错误。

基本信息

向导从基本步骤开始:

  1. 你需要首先指定的是Contributor访问角色,位于订阅级别。如果你是从packt-azureml-rg启动向导的。

  2. 输入packt-learning-mlw,这是一个受Azure Cloud Adoption FrameworkAzure CAF)命名规范启发的名称。

  3. 你需要选择一个区域来部署 Azure ML 工作区。该区域是你将要部署 Azure ML 工作区所需资源的 Azure 数据中心。列表已经筛选,仅包含具有该产品可用的所有数据中心。

    在选择 Azure 区域部署资源时,有三件事需要考虑。它们包括合规性和数据驻留要求、服务可用性以及定价。一个例子可能是你需要使用某些具有特定图形处理单元GPU)的专用虚拟机大小,例如 NV 系列,它配备了 Tesla M60——这种虚拟机大小在任何加拿大 Azure 区域都不可用。对于本书,你应该选择离你最近的区域。

  4. 可选地,你可以修改存储帐户或容器注册表名称中的hyphen (-)名称。此外,存储帐户、密钥库和容器注册表的名称必须是唯一的。你将在本章的探索已部署的 Azure 资源部分中了解更多关于这些资源的内容。如果已存在同名资源,系统会提示你更改名称。图 2.7展示了填写后的基本向导页面。

图 2.7 – 向导基本步骤中选择的信息

图 2.7 – 向导基本步骤中选择的信息

填写完所有基本信息后,你可以点击审查 + 创建按钮,并跳过所有中间步骤。这意味着你自动接受其余向导步骤的默认选项。然而,为了学习目的,你应该点击下一步:网络按钮,导航到下一个向导页面。

重要提示

直到 2020 年 9 月,这些向导的第一页要求选择Basic版本和Enterprise版本。Enterprise版本提供了设计器和你将在本书中看到的自动化 ML 功能。从 2020 年 10 月起,所有功能都可以在Basic版本中使用。原始认证中有关于哪个功能属于哪个版本的问题——这种情况在你的考试中应该不会遇到。

网络

在此向导页面,你需要决定如何计划连接到 Azure ML 工作区的数据平面。数据平面包含你工作区内所有以数据为中心的操作,例如使用 Azure ML Studio Web 界面、触发 ML 管道以及通过软件开发工具包SDK)进行 API 调用。共有两种选择,如下所示:

  • 公共端点(所有网络):这是默认选项,允许你从一个公开可访问的端点访问工作区。

  • 私有端点:私有端点通过减少 Azure ML 工作区的攻击面来降低数据外泄的风险。一旦你决定为工作区提供私有端点连接,你将需要有一个虚拟机或虚拟专用网络VPN)连接,以便访问你将暴露的私有端点:

图 2.8 – 私有端点保障对 Azure ML 工作区的访问

图 2.8 – 私有端点保障对 Azure ML 工作区的访问

对于本书的目的,你将选择公共端点(所有网络)

图 2.9 – 创建向导中的网络选项

图 2.9 – 创建向导中的网络选项

在下一页,你将选择高级选项。

高级

在此向导页面,你可以配置一些关于工作区安全性、元数据和指标数据隐私的选项。

  1. 你可以配置 AzureML 工作区使用的托管身份来进行身份验证并访问其他云资源。你可以选择系统分配的身份用户分配的身份。系统分配的身份将在你部署 AzureML 资源时自动创建。相反,你可以在 Azure 门户中创建一个用户分配的托管身份资源,并在部署 AzureML 工作区时使用它。使用用户分配的选项允许你事先创建身份,配置对各种系统和数据源的访问权限,然后将其分配给工作区。你甚至可以在其他服务中使用相同的身份,例如 Azure 自动化帐户。你可以在本章的进一步阅读部分了解更多关于托管身份的信息。在本书中,你将使用默认选项,即系统分配的身份

  2. 您可以定义 AzureML 工作区如何访问存储在默认存储帐户中的数据。基于凭据的访问使用存储帐户访问密钥来读取数据。您可以将此方法视为使用一个由所有有权访问 AzureML 工作区的人共享的密码来访问该存储帐户中的数据。在某些组织中,出于安全原因,禁止使用存储帐户访问密钥。在这种情况下,应该使用基于身份的访问。当您选择该选项时,AzureML 使用其托管身份来访问存储帐户中的数据并写入工件,如训练后的模型。此外,当数据科学家访问存储在默认存储帐户中的数据集时,他们的身份将传递到存储帐户中,以进行身份验证并提供数据。为了本书的目的,您将使用基于凭据的访问

  3. 默认情况下,Azure 机器学习服务使用 Microsoft 管理的存储,并通过 Microsoft 管理的加密密钥存储度量和元数据。您可以指定自己的密钥来加密度量和元数据。为此,您需要选择存储在现有密钥保管库中的密钥。此操作将为您在一个新的资源组中提供一些额外的 Azure 资源,其中包括一个 Cosmos DB,资源组的名称将基于模式_,例如 packt-learning-mlw_ab07ab07-ab07-ab07-ab07-ab07ab07ab07。您对这些资源没有任何控制权。它们的生命周期管理由 Azure 机器学习工作区处理,这意味着当您删除工作区时,这些资源将自动删除。

  4. 向导步骤中的最后一个选项允许您限制在工作区收集的遥测和度量数据的数量。您可以通过选择Environment来实现:通常,您会为代码库设置多个环境,例如开发环境、质量保证测试环境和生产环境。为了本书的目的,您应该指定Development值。

如果需要,您可以添加额外的元数据标签。标签的数量最多为 50,这是每个资源当前支持的标签数量上限:

图 2.11 – 创建向导中的标签步骤

图 2.11 – 创建向导中的标签步骤

完成后,点击下一步:审查 + 创建以进入向导的最后一步。

审查 + 创建

这是向导的最后一步。如果您忘记完成某些操作或在先前的步骤中做出了无效选择,您将收到错误消息,红点将指示出错的步骤:

图 2.12 – 基本步骤中出现错误验证,指示存在问题

图 2.12 – 基本步骤中出现错误验证,指示存在问题

  1. 如果一切正常,将会看到 keyVaultNamestorageAccountNameapplicationInsightsName 的 JSON 值。这个模板可以从该视图立即部署,或者你可以下载它,并将其用于在不同的订阅中配置这些资源。例如,假设你希望使用相同的资源结构来配置生产环境。你可以使用这个自动生成的 ARM 模板,修改目标 资源组、相应的资源名称和标签值,并将其部署到生产环境中。请注意,你指定的资源名称需要是唯一的,可能需要进行一些尝试,直到找到一个可用的名称。

  2. 点击 创建 按钮以配置你的 Azure ML 工作区资源。资源将开始部署。这个过程可能需要几分钟才能完成。

    最后,你应该会看到一个名为 转到资源 的按钮,可以通过它导航到新配置的 Azure ML 工作区:

 图 2.14 – “转到资源”按钮,表示 Azure ML 工作区部署成功

图 2.14 – “转到资源”按钮,表示 Azure ML 工作区部署成功

在接下来的章节中,你将学习如何使用 Azure CLI 部署相同的 Azure ML 工作区,Azure CLI 是在 Azure 中部署资源的最流行方式之一。

通过 CLI 部署 Azure ML

在这一节中,你将通过 Azure CLI 部署一个 Azure ML 工作区。你将使用 packt-azureml-cli-rg 资源组来部署资源;你将使用 Azure 门户中内置的 Bash 版本的 Azure Cloud Shell,这不需要在你的机器上进行任何安装。如果你愿意,你可以按照 docs.microsoft.com/cli/azure/install-azure-cli 中的安装说明在本地安装 Azure CLI,跳过 Azure Cloud Shell 的配置。

重要提示

在接下来的章节中,你将使用 Azure CLI 管理 Azure ML 工作区的各个方面。尽管本书假设你选择了 Azure Cloud Shell,但你将看到的语法适用于 Azure Cloud Shell 和在本地机器上运行的 Azure CLI。

部署 Azure Cloud Shell

Azure Cloud Shell 是一个基于浏览器的 Shell,允许你管理 Azure。你可以通过访问 shell.azure.com 专用页面或通过点击 Azure 门户顶部栏中的 Cloud Shell 图标来访问它:

 图 2.15 – Azure 门户顶部栏中的 Cloud Shell 图标

图 2.15 – Azure 门户顶部栏中的 Cloud Shell 图标

让我们开始吧!

  1. 当你第一次调用 Cloud Shell 时,你将看到欢迎向导。选择 Bash 继续:图 2.16 – Azure Cloud Shell 欢迎向导

    图 2.16 – Azure Cloud Shell 欢迎向导

  2. Azure Cloud Shell 需要一个文件共享来保存文件。在向导的下一步中,您可以选择一个订阅;门户将自动为您部署一个存储账户。根据您在订阅级别的权限,向导将会创建一个新的资源组,或者使用一个您拥有 Contributor 角色的资源组。

    如果您想微调此过程,您可以选择 显示高级设置 选项,并手动创建新的资源组,或定义将被 Cloud Shell 使用的存储账户名称和文件共享名称:

    图 2.17 – 配置 Cloud Shell 时的高级设置

    图 2.17 – 配置 Cloud Shell 时的高级设置

  3. 对于本书的目的,您应允许向导自动为您创建一个存储账户,通过选择您拥有的 订阅,然后点击 创建存储 按钮而无需配置高级设置:图 2.18 – 创建存储账户向导页面,正在配置 Cloud Shell

图 2.18 – 创建存储账户向导页面,正在配置 Cloud Shell

稍等片刻,一个存储账户将会被创建,您的 Cloud Shell Bash 提示符应当出现:

图 2.19 – Azure Cloud Shell 中的 Bash 提示符

图 2.19 – Azure Cloud Shell 中的 Bash 提示符

现在您已经拥有了一个 Cloud Shell,您可以使用 Azure CLI 来管理您的 Azure 资源;这将在下一部分中教您如何操作。

使用 Azure CLI

Azure CLI 是一个管理命令行工具,您可以通过输入 az 命令来调用它。通过这个工具,您可以配置和管理您的 Azure 资源。学习 Azure CLI 最简单的方式是使用任何命令末尾的 --help 参数。例如,您可以从 az --help 开始。这将列出所有可用的命令,如 login 命令、find 命令以及子组,包括 storage 子组:

图 2.20 – az 命令的子组和命令

图 2.20 – az 命令的子组和命令

您可以通过将不同的子组和命令附加到 az 命令来继续探索。例如,我们可以通过输入 az group --help 来探索 group 子组。接着,我们将研究 list 命令,通过输入 az group list --help 来发现所有可用的选项:

图 2.21 – az group list 命令帮助页面

图 2.21 – az group list 命令帮助页面

Azure CLI 的另一个有用功能是 az find 命令,它可以在 Azure 文档中搜索相关信息:

图 2.22 – 使用 az find 查找 Azure CLI 命令

图 2.22 – 使用 az find 查找 Azure CLI 命令

您可以通过运行az group list -o table命令列出所有您有权限访问的资源组,其中我们已指定输出格式为表格:

图 2.23 – 通过 Azure CLI 列出您有访问权限的所有资源组

图 2.23 – 通过 Azure CLI 列出您有访问权限的所有资源组

提示

如果您发现自己无法理解为什么输入的 Azure CLI 命令没有按预期工作,可以使用--verbose标志。如果您需要更多的信息,可以将其与--debug标志结合使用。

在接下来的部分中,您将探索可以通过 Azure CLI 执行的最常见操作。

在 Azure CLI 中进行身份验证

如果您收到错误信息,提示您使用az login命令,这将提示您打开一个页面并输入代码。此过程称为交互式设备身份验证。您将在第七章中了解更多关于此过程的信息,The AzureML Python SDK部分。

访问网页并输入代码后,您需要使用具有访问权限的帐户登录 Azure 订阅,才能通过 Azure CLI 控制该订阅。这样做将授权 Azure CLI 代表您执行操作。您随时可以通过输入az logout退出 Azure CLI。

选择活动的 Azure 订阅

如果您可以访问多个 Azure 订阅,则需要指定哪个订阅是活动订阅。要列出您的订阅,请输入az account list -o table;您可以通过输入az account set --subscription "订阅名称或 ID"来激活某个订阅,并传入要通过 Azure CLI 控制的订阅名称或 ID。

从 Azure CLI 创建资源组

互联网上最常见的 Azure CLI 命令之一就是创建资源组命令,它是一个虚拟文件夹,您可以在其中部署 Azure 资源。以下命令将创建一个名为packt-azureml-cli-rg的资源组,并将该新资源组的记录保存在西欧的 Azure 数据中心中:

az group create --name packt-azureml-cli-rg --location westeurope

--name参数的快捷方式是-n。类似地,-l--location的快捷方式。前面的命令现在可以写成如下:

az group create -n packt-azureml-cli-rg -l westeurope

-n-l快捷方式在许多 Azure CLI 命令中都很常见。

重要提示

您需要在订阅级别拥有Contributor角色,才能创建资源组。更准确地说,您需要一个允许执行Microsoft.Resources/subscriptions/resourceGroups/write操作的角色,您将在本章后面出现的理解基于角色的访问控制(RBAC)部分中了解更多相关信息。

在接下来的部分中,您将学习如何在 Azure CLI 中安装扩展:一个用于管理 Azure ML 工作区的扩展。

安装 Azure ML CLI 扩展

要通过 Azure CLI 管理 Azure ML 工作区,你需要安装az extension add -n azure-cli-ml

要查看当前已安装的扩展及其版本,输入az extension list -o table

图 2.24 – 包括 azure-cli-ml 在内的所有已安装扩展的列表

图 2.24 – 包括 azure-cli-ml 在内的所有已安装扩展的列表

要将已安装的扩展更新到最新版本,请输入az extension update -n azure-cli-ml

你刚刚安装的扩展已将ml命令子组添加到 Azure CLI 中。你可以通过使用az ml --help命令来检查该子组及其包含的命令。在下一节中,你将使用这些新命令来部署 Azure ML 工作区。

使用 az ml 命令部署 Azure ML

本节的目标是在名为packt-azureml-cli-rg的资源组中部署名为packt-learning-cli-mlw的 Azure ML 工作区,并附加Environment标签,值为Development

要配置一个新的 Azure ML 工作区,你需要使用az ml workspace create命令。

唯一需要的选项是--workspace-name-w,即工作区名称。这样会在你的 Azure 订阅中创建一个新的资源组并在其中部署新的工作区。这要求你至少在订阅级别具有Contributor角色,否则会收到授权错误。

为了指定你希望部署新工作区的目标资源组,你需要传递--resource-group选项或-g选项。

重要提示

一些常见的az ml参数:-g-w参数在所有 Azure ML CLI 命令中都是常见的,你将在本书的后续部分再次使用它们。

要将标签附加到新创建的资源,可以使用--tags参数或-t参数,后者使用key=value语法。

输入以下命令以部署请求的 Azure ML 工作区:

az ml workspace create -g packt-azureml-cli-rg -w packt-learning-cli-mlw -t Environment=Development

结果如下图所示:

图 2.25 – 通过 CLI 扩展部署 Azure ML 工作区

图 2.25 – 通过 CLI 扩展部署 Azure ML 工作区

在本节中,你学习了如何使用 Azure CLI 部署 Azure ML 工作区。对于本书,你只需要通过用户界面配置的那个,下一节中你将删除刚刚配置的那个。

清理 CLI 资源组

本书的目的,你需要一个 Azure ML 工作区。你将使用通过 Azure 门户在packt-azureml-rg资源组中部署的工作区。如果你愿意,可以通过执行以下命令删除新配置的 Azure ML 工作区:

az ml workspace delete -g packt-azureml-cli-rg -w packt-learning-cli-mlw --all-resources

这将删除 Azure ML 工作区以及前面步骤中配置的所有相关资源。

到目前为止,您已经探索了通过门户和 Azure CLI 部署 Azure ML 工作区的最常见方式。在下一节中,您将学习几种额外的方法,包括 DevOps 工程师首选的 ARM 方法。

部署 Azure ML 工作区的替代方法

还有其他方式可以部署 Azure ML 工作区:

  • 创建 ARM 模板。这是 Azure 原生的资源描述方式,您可以通过 JSON 文件描述要部署的资源。有关 Azure ML 工作区的 ARM 模板示例,您可以访问 bit.ly/dp100-azureml-arm

    从 Azure CLI 部署此模板的命令如下所示:

    az deployment group create --name packt-deployment --resource-group packt-azureml-rg --template-uri https://bit.ly/dp100-azureml-arm --parameters workspaceName=packt-learning-arm-mlw location=westeurope
    

    您还可以通过选择在 Azure 门户资源创建向导最后一步的 创建 按钮左侧显示的 下载自动化模板 链接来找到 ARM 模板。

  • 通过 Azure ML Python SDK,您将在 第七章 中了解 Azure ML Python

  • 通过 Azure 管理 REST API,如在 docs.microsoft.com/azure/machine-learning/how-to-manage-rest#create-a-workspace-using-rest 中所述。

在下一节中,您将探索已部署到目标资源组的 Azure 资源,并学习如何为同事提供工作区访问权限。

探索已部署的 Azure 资源

打开 Azure 门户并搜索资源组。选择图标以导航到您有权限访问的资源组列表,如下图所示:

图 2.26 – 导航到资源组列表

图 2.26 – 导航到资源组列表

选择 packt-azureml-rg 选项并观察在该资源组内部署的资源:

  • ML 工作区资源命名为 packt-learning-mlw。这是您部署的主要资源。通过该资源,您可以管理工作区的各个方面。

  • 一个名为 packtlearningm<random_number> 的 Azure 密钥保管库服务。此密钥保管库用于安全存储您将在 Azure ML 工作区中使用的凭据和访问密钥。

  • 一个名为 packtlearningm<random_number> 的存储帐户。此存储帐户在配置过程中自动生成,用于存储来自工作区的文件,包括实验数据集和模型。

  • 一个名为 packtlearningm<random_number> 的应用洞察帐户。这是您将在 Azure ML 工作区中发布的所有预测端点的监视服务。

这些是自动部署到 Azure ML 工作区的开箱即用组件:

图 2.27 – packt-azureml-rg 资源组中的资源列表

图 2.27 – packt-azureml-rg 资源组中的资源列表

其实还有一个资源会在你运行第一个实验时自动配置:一个Azure 容器注册表ACR)。这个注册表将托管各种Docker容器镜像,包括将要暴露一个网页服务器,该服务器会基于你训练的人工智能AI)模型进行推理。

当你想为模型部署实时端点时,你可以在Azure 容器实例ACI)或Azure Kubernetes 服务AKS)中进行部署,这一操作可以在 Azure ML Studio 中完成。你将在本书的第五章《让机器进行模型训练》中首次部署 ACI,你会注意到一个 ACI 资源会出现在该资源组中,旁边是现有的资源。

理解基于角色的访问控制(RBAC)

Azure 提供了 RBAC,允许你定义每个角色在特定资源上可以执行的操作。每个角色会根据特定的范围分配,例如,如果你在某个资源组中被分配了贡献者角色,你只能在该资源组内配置资源,而无法在订阅级别进行操作。Azure 默认提供了三种常见的角色:

  • 读取者:这个角色允许你浏览 Azure 资源,但无法修改或激活任何内容。

  • 贡献者:这个角色基于读取者角色,并允许你编辑资源或在角色的范围内创建新资源。这个角色不允许修改附加到资源的权限。这意味着你不能授予其他用户对你可能配置的资源的权限。

  • 所有者:这个角色可以执行贡献者角色所做的所有操作,还可以在此角色适用的范围内分配和修改角色。

让我们来查看在你部署 Azure ML 工作区的资源组中分配的角色。点击资源组的访问控制(IAM)标签,然后选择角色分配。在这个页面上,你将看到在资源组级别的角色分配列表。注意,你的账户至少已经在该资源组中被分配了贡献者角色,以便配置资源。如果你在列表中没有看到自己的账户,可能是因为你是管理员,试着查看经典管理员标签下的内容:

图 2.28 – 访问控制(IAM)页面上的角色分配来自 packt-azureml-rg 资源组

图 2.28 – packt-azureml-rg 资源组的访问控制(IAM)页面上的角色分配

当您配置工作区时,会创建一个新的系统分配的托管身份,名称与您配置的 Azure ML 工作区相同。这个身份自动被分配为资源组的贡献者角色。这允许 ML 工作区在该资源组内部署 ACI 资源并访问计算目标和数据存储。请注意,此身份由平台本身使用,不应被用于分配对外部资源的访问权限等。

接下来,您将了解该角色分配如何流向资源。

RBAC 继承

打开packt-learning-mlw资源,点击访问控制(IAM)选项卡,然后选择角色分配

请注意,资源组中存在的角色会继承到 Azure ML 工作区资源:

图 2.29 – 来自资源组的 packt-learning-mlw 中的 RBAC 继承

图 2.29 – 来自资源组的 packt-learning-mlw 中的 RBAC 继承

角色分配从订阅继承到资源组,然后从资源组继承到资源。在订阅之上,还有一个分组层,称为管理组,它允许您构建包含其他管理组或订阅的层次结构。以下是整体 RBAC 继承模型的示意图:

图 2.30 – RBAC 继承模型

图 2.30 – RBAC 继承模型

现在您已经知道如何分配现成的角色并理解继承是如何工作的,在下一节中,您将学习如何为您的 Azure ML 工作区创建自定义角色。

创建自定义角色

Azure 允许您创建自定义 RBAC 角色,您可以精细调整哪些操作被允许,哪些操作不被允许;这类似于允许列表和阻止列表。门户提供了一种图形化体验,允许您在资源组级别或更高的级别创建自定义角色。此体验的结果是一个 JSON 文件,如下所示的示例:

{
    "Name": "ACI model deployer role",
    "IsCustom": true,
    "Description": "Can deploy registered model on ACI resources",
    "Actions": [
"Microsoft.MachineLearningServices/workspaces/services/aci/write"
    ],
    "NotActions": [ ],
    "AssignableScopes":["/subscriptions/<subscription_id>"]
}

这是一个非常简单的自定义角色,名为ACI 模型部署者角色,它为工作区的 ACI 服务提供写入访问权限——这是通过字面值Microsoft.MachineLearningServices/workspaces/services/aci/write来编码的操作。

一个更复杂的自定义角色示例如下:

{
    "Name": "Limited Data Scientist",
    "IsCustom": true,
    "Description": "Limited data scientist role",
    "Actions": ["*"],
    "NotActions": [
"Microsoft.MachineLearningServices/workspaces/computes/delete",
"Microsoft.Authorization/*/write"
    ],
    "AssignableScopes": [        
"/subscriptions/<subscription_id>/resourceGroups/<resource_group_name>/providers/Microsoft.MachineLearningServices/workspaces/<workspace_name>"
    ]
}

请注意,与之前的角色显式允许单个操作不同,此角色在允许的操作中使用了通配符(*),这意味着它可以执行所有可用操作。为了限制这种效果,我们使用了 NotActions 部分,它指示哪些操作被明确拒绝。在此示例中,我们明确禁止删除计算资源的操作(Microsoft.MachineLearningServices/workspaces/computes/delete),并且不能更新该工作区的任何授权方面(Microsoft.Authorization/*/write)。注意,通配符可以用于匹配部分操作,例如在 Microsoft.Authorization 操作中,通配符匹配操作组,如 lockroleAssignmentsroleDefinitions。在我们的案例中,我们希望拥有此角色的用户不能向工作区添加新用户,因此我们希望拒绝 Microsoft.Authorization/roleAssignments/write 操作,而该操作已被我们使用的通配符表达式所覆盖。

最后,AssignableScopes 允许你指定此角色的作用范围。这是一个必填字段。在第一个示例中,你将此角色的作用范围限制在 ID 为 <subscription_id> 的 Azure 订阅中。在这种情况下,你可以将此自定义角色分配给属于该订阅 ID <subscription_id> 的任何资源组或资源。在第二个示例中,你将此自定义角色的作用范围限制在名为 <workspace_name> 的 Azure ML 工作区中,该工作区部署在名为 <resource_group_name> 的资源组中,并且属于 <subscription_id> 订阅。这意味着你不能将此自定义角色分配到其他地方,因为它具有非常特定的可分配作用范围。

如果你希望通过 Azure CLI 在 Azure 中部署自定义角色,可以使用以下命令:

az role definition create --role-definition custom_role.json

这里,custom_role.json 是包含你要在 Azure 中部署的自定义角色的 JSON 角色定义文件。

一旦角色部署到 Azure,你可以将该特定角色分配给某个用户。

在 Azure ML 工作区中分配角色

将角色分配给用户是一项特权操作,意味着你正在修改资源的权限。为此,你需要拥有你想要修改的资源的 Owner 权限。更准确地说,你需要一个允许你使用 Microsoft.Authorization/roleAssignments/write 操作的角色——这是内置的 Owner 角色所具备的权限。

如果你拥有 Owner 权限,你可以将你在前一部分中创建的 ACI 模型部署角色 分配给某个用户。你可以通过以下三种方式进行操作:

  • 在 Azure 门户中,你可以访问你想要的 Azure ML 工作区,并通过 理解基于角色的访问控制(RBAC) 部分中看到的 访问控制(IAM) 选项卡将角色分配给用户。

  • 通过 Azure CLI 执行以下命令:

    user id. Then, you apply this assignment at the level of the Azure ML workspace. To get the user ID of the user with the email username@organization.org, you can use the following Azure CLI command:
    
    

    az ad user list --query "[?mail=='username@organization.org'].objectId" --output tsv

    
    
  • 通过使用以下命令的 Azure ML CLI 扩展:

    az ml workspace share -w packt-learning-mlw -g packt-azureml-rg --role "ACI model deployer role" --user username@organization.org
    

通过这些步骤,你可以通过创建自定义角色来与同事共享工作区,从而细化允许的权限。

总结

在这一章中,你了解了部署 Azure ML 的前提条件。你可以使用试用订阅,也可以在你公司订阅中请求一个资源组,在那里你至少具有该资源组的贡献者权限。你还深入了解了在开发环境中部署 Azure ML 工作区的两种最常见方式,并且你掌握了需要指定的参数。你还了解了部署工作区的其他方式,包括 ARM 模板,这是一种更适合 DevOps 的生产环境部署方式。在最后一部分,你了解了部署 Azure ML 工作区所涉及的资源,并学习了 RBAC 在 Azure 中的工作原理。此外,你还学习了如何使用内置角色或自定义角色来授予对已部署 Azure ML 工作区的访问权限。

在下一章,你将学习 Azure ML Studio 的使用体验,它是一个支持管理端到端 ML 生命周期的 Web 环境。

问题

在每一章中,你应该会找到几个问题,帮助你对本章讨论的主题进行知识检查:

  1. 以下哪些是适用于部署 Azure ML 工作区的方式?

    a. 通过 azure-cli-ml 扩展的 Azure CLI

    b. Azure 门户

    c. 部署 ARM 模板

    d. Azure ML Python SDK

  2. 你正在创建一个自定义角色,并希望拒绝删除工作区的权限。你需要在 JSON 定义的哪个部分添加 Actions 部分?

    b. 添加到 JSON 定义的 NotActions 部分

    c. 添加到 JSON 定义的 AssignableScopes 部分

  3. 在 Azure CLI 中,你需要安装什么才能部署 Azure ML 工作区?

进一步阅读

本节提供了一些有用的网络资源,可以帮助你拓展对 Azure 的知识和理解:

第三章:第三章:Azure 机器学习工作室组件

在本章中,你将探索 Azure 机器学习工作室Azure ML Studio)的 Web 界面,这是一种用于管理端到端机器学习生命周期的沉浸式体验。你将获得有关可用组件的概述,这些组件允许你管理工作区资源、编写机器学习模型并跟踪你的资产,包括数据集、训练过的模型及其发布的端点。

在本章中,我们将覆盖以下主要主题:

  • 与 Azure ML 资源交互

  • 探索 Azure ML Studio 体验

  • 在 Azure ML Studio 中编写实验

  • 在 Azure ML Studio 中跟踪数据科学资产

  • 在 Azure ML Studio 中管理基础设施资源

技术要求

你需要有一个 Azure 订阅。在该订阅下,你需要一个 packt-azureml-rg。你还需要拥有 ContributorOwner 权限的 packt-learning-mlw。如果你按照 第二章 中的说明操作,这些资源应该已经对你可用,部署 Azure 机器学习工作区资源

与 Azure ML 资源交互

在上一章中,你在 packt-azureml-rg 资源组内部署了 packt-learning-mlw 机器学习资源。通过在顶部搜索栏中输入资源名称并从结果列表中选择该资源来导航到已部署的资源:

图 3.1 – 导航到 Azure 机器学习资源

图 3.1 – 导航到 Azure 机器学习资源

这将把你带到该资源的概述窗格,如 图 3.2 所示:

  1. 在左侧,你将看到大多数 Azure 服务都有的典型资源菜单。这个菜单也被称为左侧窗格。

  2. 在顶部,你将看到命令栏,它允许你下载 config.json 文件,该文件包含连接到工作区所需的所有信息,使用 Python SDK 连接到工作区,并删除机器学习工作区。

  3. 在命令栏下方,你可以看到工作窗格,这是你可以查看与工作区相关的信息的地方,包括链接到存储帐户、密钥保管库、容器注册表和与此工作区一起部署的应用程序洞察资源:

图 3.2 – 机器学习资源页面

图 3.2 – 机器学习资源页面

在左侧窗格中,你将找到所有 Azure 资源中常见的选项。包括以下指示性列表:

  • 访问控制 (IAM),你可以使用它来配置特定工作区的角色访问,包括分配你在前一章中创建的自定义角色。

  • 诊断设置,允许你为 Azure 机器学习工作区生成的日志和指标配置流式导出到你选择的目的地。通常,这个目的地是日志分析,它是Azure 监视的一部分。

  • 新支持请求,如果你在使用工作区时遇到问题,可以轻松请求支持。

设置部分,你还会注意到私人端点连接选项,它允许你配置一个 Azure 私人端点。这是一个虚拟网络接口,你可以将其附加到虚拟网络上。它允许该虚拟网络内的所有资源私密且安全地连接到你的 Azure 机器学习工作区。一旦启用此选项,所有数据平面操作,如使用 Azure ML Studio、API(包括发布的管道)或 SDK,都需要通过此私人端点进行。

从左侧面板选择概览选项,并点击工作面板中间的启动工作室按钮。这将在你的浏览器中打开一个新标签页,带你进入 Studio 体验。

探索 Azure ML Studio 体验

Azure 机器学习提供了一个专门的 Web 界面,允许你实施无代码和代码优先的数据科学计划。你可以通过 Azure 门户资源中的启动工作室按钮访问该 Web 界面,正如你在前一部分所看到的,或者直接访问ml.azure.com页面。采用后者的方法,如果这是你第一次访问 Studio 站点,你需要手动选择Azure Active Directory租户、订阅以及你想要连接的机器学习工作区的名称,如图 3.3所示。

图 3.3 – 在 ml.azure.com 中选择机器学习工作区

图 3.3 – 在 ml.azure.com 中选择机器学习工作区

一旦你选择了工作区,你将进入 Azure 机器学习 Studio 的主页,如图 3.4所示。

图 3.4 – Azure 机器学习 Studio 主页

图 3.4 – Azure 机器学习 Studio 主页

在左侧,你有一个菜单,提供以下类别,所有这些都会在接下来的部分中探索:

  • 作者:使用创作工具构建、训练、评估和部署机器学习模型。

  • 资源:准备数据,运行和监控作业,查看和部署模型,以及管理实时和管道端点。

  • 管理:查看和管理工作区的资源。

你可以通过点击左上角的图标来收起菜单,如下图所示:

图 3.5 – 收起的侧边菜单

图 3.5 – 收起的侧边菜单

在右上角,如图 3.6所示,你有以下选项:

  1. 登录信息:显示登录用户的信息,并允许你登出。

  2. 工作区选择器:允许你更改正在使用的 Azure 机器学习工作区。

  3. 提供反馈:允许你发送笑脸或皱眉表情给 Azure 机器学习团队,帮助他们改进你不喜欢的地方或突出你喜欢的部分。

  4. 帮助:提供帮助资源和文档的链接。该菜单还允许你运行工作区诊断,识别工作区的潜在配置问题。

  5. 设置:在此,你可以选择深色主题选项,并更改 Studio 的语言和地区格式。

  6. 通知:该菜单选项允许你管理将收到的工作区通知。例如,实验运行完成后,你会收到通知。

图 3.6 – 右上角菜单

图 3.6 – 右上角菜单

在下一节中,我们将查看左侧菜单的各个部分,从创作部分开始。

在 Azure ML Studio 中创作实验

Azure ML Studio 提供以下创作体验:

  • 笔记本:允许你直接在工作区内使用文件、文件夹和Jupyter 笔记本。你将在第七章AzureML Python SDK 中使用笔记本,在那里你将看到以代码为主的数据科学过程。

  • 自动化机器学习(Automated ML)允许你快速测试多种算法组合,以找到基于你定义的成功指标的最佳模型。你将在第五章让机器完成模型训练中了解更多内容。

  • 设计器允许你通过连接数据集和模块(如数据转换和模型训练)在流程中可视化设计实验。通过在画布上设计这个流程,你可以在不编写任何代码的情况下训练和部署机器学习模型,你将在第六章视觉模型训练与发布中详细了解这一内容。

  • 数据标注允许你创建标注项目来整理数据集。这使你能够将标注工作扩展到多个标注员,协调标注工作的效率,并通过机器学习辅助(ML Assist)增强标注员的生产力,ML Assist 会在你标注数据时自动进行训练。

自动化机器学习(Automated ML)和设计器是无代码/低代码数据科学方法的一部分,你将在本书的后续章节中深入探讨这一点。

重要提示

数据标注目前位于左侧菜单的管理部分。然而,它在逻辑上是 Azure ML Studio 提供的创作体验的一部分。由于 Studio 体验不断发展,这项功能可能会在不久的将来移至创作部分。

在 Azure ML Studio 中跟踪数据科学资产

在资产部分,您可以跟踪所有与机器学习操作相关的组件。每个数据科学项目都有以下资产:

  • 数据集是您可以找到注册数据集的地方。这是一个集中注册表,您可以在其中注册数据集,避免同事们不得不在相同数据的本地副本上工作,或者更糟的是,数据的子集。您将在第四章配置工作区中使用数据集。

  • 实验是一个集中式的位置,用于跟踪脚本执行或运行的组。当您训练模型时,您会记录该过程的各个方面,包括您可能需要用来比较性能的指标。为了将所有尝试归为同一上下文,您应将所有运行提交到同一个实验名称下;然后,结果将在此区域中显示。您将在第五章让机器进行模型训练中使用实验。

  • 管道允许您创建和管理协调机器学习步骤的工作流。例如,一个非常常见的机器学习训练工作流包含三个步骤:数据处理、模型训练和模型注册。管道可以是机器学习训练管道,就像前面的示例所示,或者是批量数据推理管道——换句话说,管道使用机器学习模型对数据集进行推理。在本节中,您可以查看所有已注册的管道,监控它们的执行情况,并查看发布的端点,这些端点允许您临时触发其中的一个管道。您将在第十一章使用管道中使用管道。

  • 模型是您的机器学习模型的注册表。在这里,您可以跟踪它们的版本。它允许您通过网页界面立即部署。要发布模型,您需要先在该注册表中注册它。您将在本书的整个过程中使用该注册表,从第五章让机器进行模型训练开始。

  • 端点由两部分组成:实时端点和管道端点。实时端点是托管在Azure 容器实例ACI)或Azure Kubernetes 服务AKS)中的 Web 应用程序,它们暴露一个 REST API,允许第三方应用程序使用您已部署的机器学习模型。而管道端点是允许您触发之前在相应部分注册的管道的端点。

所有前述的经验是相互关联的,您会发现自己在探索实验时会从一个部分导航到另一个部分:

图 3.7 – Azure ML 中的互联资产

图 3.7 – Azure ML 中的互联资产

运行机器学习实验的前提是拥有能够执行训练脚本的计算资源。你还需要能够存储并提供访问你注册为数据集的数据的引擎。这些资源将在下一部分进行管理。

在 Azure ML Studio 中管理基础设施资源

要进行实验,你需要一些基础设施资源来进行消耗。你可以通过以下几个部分进行配置和管理:

  • 计算提供了你可以在实验中使用的托管计算基础设施。这让你可以注册并利用可能拥有多个 CPU 和 GPU 以及能够加载海量数据集的内存的虚拟机。作为托管服务的计算资源意味着你不必担心安装操作系统或保持它的更新和修补。你将在第四章中了解更多关于各种计算选项的内容,配置工作区

  • 数据存储包含了访问各个引擎中数据所需的连接信息,如Azure Blob 存储Azure SQL 数据库。这些信息用于访问你在计算部分注册的数据集。你将在第四章中了解更多关于数据存储的概念,配置工作区

  • 链接服务允许你查看外部服务与工作区之间的连接。例如,你可以连接你的 Synapse Spark 池,并使用 Spark 运行数据准备任务。

  • 环境允许你指定代码执行所需的软件要求。例如,如果你正在训练一个 PyTorch 模型,你将需要在执行训练脚本的环境中安装 PyTorch 库。你将在第八章中了解更多关于环境的内容,使用 Python 代码进行实验

总结

Azure Machine Learning Studio 提供了一个网络环境,在这里你可以管理 Azure Machine Learning 工作区中的所有工件。你可以查看和管理你的 Jupyter 笔记本、数据集、实验、管道、模型和端点。你还可以管理将在实验中使用的计算资源和数据存储。Studio 还提供了交互式工具,你可以使用这些工具进行无代码数据科学实验,这些内容将在本书的后续章节中深入讲解。AutoML 向导是第一个内置于 Azure ML Studio 的无代码体验,它允许你运行自动化机器学习实验。Azure Machine Learning 设计器是下一个无代码体验,帮助你通过图形化方式设计管道和创建工作流,无需编写代码。这个体验还支持低代码场景,在需要时你可以插入代码片段。最后,数据标注项目让你能够创建、管理并监控需要标注数据的繁琐项目。

要开始使用这些交互式工具,你至少需要配置一个计算资源。此外,你还需要注册你的数据存储。这些数据存储将托管你在模型训练阶段使用的数据。

在下一章中,你将学习如何通过 Azure ML Studio 执行这些操作。

第四章:第四章:配置工作区

在本章中,您将进入 Azure 机器学习ML)Studio 网页界面,并学习如何配置运行实验所需的基础设施。接着,您将学习如何配置或附加到现有的计算资源,并建立 Azure ML 工作区与托管您数据的各种数据存储之间的连接。配置好这些资源后,您将能够注册数据集并探索 Azure ML 提供的监控数据集的功能。

在本章中,我们将涵盖以下主要主题:

  • 配置计算资源

  • 连接到数据存储

  • 使用数据集

技术要求

您需要拥有一个 Azure 订阅。在该订阅中,您需要一个 packt-azureml-rg。您需要拥有 ContributorOwner 权限的 packt-learning-mlw,如第二章所述,部署 Azure 机器学习工作区资源

配置计算资源

计算资源使您能够在数据探索分析、训练阶段以及在操作化机器学习模型时执行代码脚本。Azure ML 工作区提供以下类型的计算资源:

  • 计算实例:这些是专门为每位在 Azure ML 工作区 中工作的数据科学家配置的虚拟机。

  • 计算集群:这些是可扩展的计算集群,可以并行运行多个训练或推理步骤。

  • 推理集群:这些是 Azure Kubernetes 服务AKS)集群,可以将 Docker 镜像转化为可操作的服务,通过 REST API 暴露您的模型。

  • 附加计算:这些是现有的计算资源,如 Ubuntu 虚拟机VMs)或 Synapse Spark 池,可以附加到工作区中,用于执行训练或推理管道的某些步骤。

当您访问 管理 | 计算 部分时,您将能够查看并管理这些类型,通过选择相应的标签,如下图所示:

图 4.1 – Azure ML Studio 中的计算类型

图 4.1 – Azure ML Studio 中的计算类型

在接下来的章节中,您将发现每种计算类型,并了解您必须注意的重要配置参数。

重要说明

配置和附加计算资源也可以通过 Azure ML CLI 和 Azure ML Python SDK 完成。您将在第七章中看到通过 Python SDK 配置相同资源的示例,Azure ML Python SDK

计算实例

计算实例是一个虚拟机,将为您作为数据科学家的日常工作提供支持。这是一个基于 Ubuntu 的托管工作站,预先配置了数据科学工具,如 Jupyter Labs、RStudio 以及各种深度学习框架,如 PyTorchTensorFlow托管意味着您无需手动更新操作系统或确保其修补最新的安全漏洞。

重要说明

计算实例非常适合那些可能无法在公司电脑上安装 Python 的企业用户。计算实例仅要求您具备现代网页浏览器和互联网连接。连接到计算实例后,您将能够访问所有工作 Azure ML 工作区所需的软件包。

您的所有文件和偏好设置都安全地存储在虚拟机的/home/<username>/cloudfiles/code/文件夹中。此文件夹不属于虚拟机的磁盘,但它是从您 Azure ML 存储帐户中位于远程文件共享的位置挂载的,如下图所示。此文件共享允许您跨多个计算实例共享代码文件和笔记本,您甚至可以在自己的计算机上本地挂载该文件夹:

图 4.2 – 挂载到多个计算实例上的远程文件共享

图 4.2 – 挂载到多个计算实例上的远程文件共享

计算实例主要用于支持 Studio 网页界面的 笔记本 功能,但它们也可以用于小规模的训练和推理。实际上,计算实例提供了作业排队功能,允许您每个核心运行多达两个作业,这对于测试和调试场景非常有用。稍后在本章的 数据漂移检测 部分,您将使用计算实例执行数据漂移分析。在下一节中,您将学习如何配置您的第一个计算实例。

配置计算实例

让我们学习如何配置一个实例:

  1. 在 Studio 网页界面中,导航至 管理 | 计算 部分并选择 计算实例 标签。如果尚未配置计算实例,您将看到计算实例的简短介绍:您可以点击 新建 按钮启动计算配置向导,如 图 4.3 左侧所示。如果工作区中已经配置了其他计算实例,您可以通过点击顶部菜单中的 新建 按钮启动相同的向导,如下图右侧所示:图 4.3 – 启动计算实例配置向导

    图 4.3 – 启动计算实例配置向导

  2. 首先,您需要选择虚拟机的大小。您可以指定是否需要启用 GPU 的机器或普通的 CPU 机器。如果您计划运行计算机视觉实验或深度神经网络训练,GPU 机器可以加速训练和推理过程,前提是框架支持 GPU。此外,您可以添加过滤器来限制列表,以满足您工作空间的最低要求。在我们的例子中,我们将选择一台仅包含 CPU 的计算实例,且至少配备 14 GB 的内存和 4 核心,如下图所示:图 4.4 – 计算实例配置向导的第一页

    图 4.4 – 计算实例配置向导的第一页

    在结果表中,您可以查看每个虚拟机的特性,并估算其每小时的费用。

    重要提示

    虚拟机的费用取决于其大小,同时也取决于其配置所在的区域。例如,在编写本书时,东部美国 2 区的每小时平均价格最低,而西欧是最昂贵的区域之一。

    下表包含了关于结果列表中前几个虚拟机大小的更多信息。Standard_D3_v2Standard_DS3_v2 虚拟机的主要区别在于其使用的高级存储磁盘。这种磁盘提供了磁盘缓存功能,使得虚拟机能够实现超越底层磁盘性能的表现。因此,向导默认建议选择 Standard_DS3_v2 虚拟机大小:

    图 4.5 – 基于 docs.microsoft.com 网站的计算实例大小比较

    图 4.5 – 基于 docs.microsoft.com 网站的计算实例大小比较

  3. 保持选择 Standard_DS3_v2 大小,然后点击 下一步 来配置计算实例的高级设置:图 4.6 – 计算实例配置向导的第二页

    图 4.6 – 计算实例配置向导的第二页

    重要提示

    如果您使用的是免费试用版,则您将有一个固定的核心配额,除非切换到按需付费订阅,否则无法更改。您可能需要选择 Standard_DS2_v2 以减少计算实例使用的核心数量。您将需要至少两个核心来为第 第七章 中要配置的计算集群提供支持,《Azure ML Python SDK》

  4. 现在,您需要提供计算机名称。这是您将用来引用特定计算机的名称。计算机名称在 Azure 区域内应该是唯一的。这意味着您可能需要将名称更改为一个唯一的名称,可能是通过在名称中添加一些数字,例如 ds-021-workstation

  5. 可选地,启用 SSH 访问标志。此选项允许你指定 SSH 密钥的公钥部分,从而使你能够远程访问计算实例。向导允许你在向导内直接生成该密钥。或者,你可以按照 生成 SSH 密钥对 部分中的说明生成密钥。如果你仅计划使用工作室体验进行数据科学实验,则不需要此选项:图 4.7 – 启用计算实例的 SSH 访问

    ](https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/az-ds-ass-cert-gd/img/B16777_04_009.jpg)

    图 4.7 – 启用计算实例的 SSH 访问

  6. 点击 创建 按钮以配置计算实例。这将完成向导。在此时,计算实例将被创建并启动:图 4.8 – 等待计算实例创建并过渡到运行状态

    ](https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/az-ds-ass-cert-gd/img/B16777_04_007.jpg)

图 4.8 – 等待计算实例创建并过渡到运行状态

在接下来的章节中,如果你不熟悉生成 SSH 密钥的过程,将简要介绍基于 SSH 密钥的认证以及如何生成 SSH 密钥。此外,你还将探索向导的高级选项,这些选项本书不需要使用。

生成 SSH 密钥对

SSH 密钥对由两个文件组成——一个私钥和一个公钥。该密钥对允许终端用户使用公钥部分加密文本。加密后的文本只能由 SSH 密钥的私钥部分解密,如下图所示。SSH 密钥的私钥部分需要存储在安全的位置,而公钥部分则可以自由分发给任何人:

图 4.9 – 私钥可以解密使用公钥加密的信息

图 4.9 – 私钥可以解密使用公钥加密的信息

利用 SSH 密钥对的这个特性,你可以将公钥配置到服务器上,从而使服务器能够使用它进行认证。简而言之,当你尝试连接到服务器时,服务器将创建一个随机的挑战,并使用你在配置计算实例时设置的公钥部分进行加密。你需要使用私钥部分解密该挑战,并以正确的答案回应,验证你成功解密了服务器的消息。这个流程将允许你通过 SSH 访问远程服务器。

有多个开源工具可以帮助你在本地计算机上生成 SSH 密钥对。Azure 提供了一种非常简单的方法,可以通过浏览器生成 SSH 密钥对,并将密钥的公钥部分作为资源存储在 Azure 门户中。让我们来看看:

  1. 访问 portal.azure.com,点击 SSH 密钥 资源并点击 创建图 4.10 – 市场中的 SSH 密钥资源

    图 4.10 – 市场中的 SSH 密钥资源

  2. 选择 packt-azureml-rg 资源组并提供一个密钥对名称,例如 azureml-compute。点击 查看 + 创建 进入向导的最后一步:图 4.11 – 生成 SSH 密钥对

    图 4.11 – 生成 SSH 密钥对

  3. 选择 azureml-compute.pem。确保将文件存储在安全的位置:

图 4.12 – 存储 SSH 密钥的私钥部分

图 4.12 – 存储 SSH 密钥的私钥部分

完成此过程后,SSH 密钥资源将在你在向导中选择的资源组中显示:

图 4.13 – 你部署的 SSH 密钥资源

图 4.13 – 你部署的 SSH 密钥资源

在该资源中,你可以找到 SSH 密钥的公钥部分,你可以将其复制并粘贴到你在配置计算实例部分看到的计算实例配置向导步骤中:

图 4.14 – 生成的密钥对的公钥部分。在顶部,你可以看到已下载的私钥部分

图 4.14 – 生成的密钥对的公钥部分。在顶部,你可以看到已下载的私钥部分

重要提示

SSH 密钥资源要求 Microsoft.Compute 提供程序在你计划使用的 Azure 订阅中注册。如果你是订阅的所有者,Azure 会在你部署资源时自动为你注册提供程序;否则,你需要请求订阅所有者为你注册该提供程序,并按照第二章中提供的说明进行操作,部署 Azure 机器学习工作区资源

到目前为止,你已经学习了如何配置计算实例并配置 SSH 密钥,这将允许你远程连接到该计算实例。你还可以使用这个 SSH 密钥连接到远程集群,接下来你将在计算集群部分进行配置。在接下来的子章节中,你将了解计算实例配置向导的高级配置选项。

高级计算实例设置

在计算资源配置向导中,你可以选择性地配置一些高级设置。其中之一是启用虚拟网络选项,它允许你将配置好的计算资源附加到一个虚拟网络中,并连接到该网络的特定子网,如下图所示:

图 4.15 – 将计算实例附加到特定子网

图 4.15 – 将计算实例附加到特定子网

此功能解锁了多种高级网络拓扑。最常见的情况是当你计划访问无法通过互联网访问的数据源时。例如,如果你有一个存储帐户,并且该帐户的防火墙设置为禁止互联网访问,通常会在特定子网中部署一个私有端点,以允许访问该存储帐户。当你配置计算实例并通过上述选项将其设置为与该子网相同时,计算实例将能够访问受保护的存储帐户,如下图所示:

图 4.16 – 通过私有端点访问仅可通过私有端点访问的存储帐户

图 4.16 – 通过私有端点访问仅可通过私有端点访问的存储帐户

向导中显示的另一个高级选项是分配给其他用户。此选项与第二章创建自定义角色部分相关,该部分介绍了如何为你的 Azure ML 工作区创建自定义角色。在企业环境中,通常不允许最终用户自行部署任何计算实例。这是通过创建自定义角色并仅允许以下虚拟机操作来实现的:

  • Microsoft.Compute/virtualMachines/start/action

  • Microsoft.Compute/virtualMachines/restart/action

  • Microsoft.Compute/virtualMachines/deallocate/action

在这些环境中,管理员(或具有Microsoft.Compute/virtualMachines/write权限的人)可以配置计算实例并将其分配给某个可能无法自行配置计算实例的特定人员,如下图所示:

图 4.17 – 将已配置的计算实例分配给另一位数据科学家

图 4.17 – 将已配置的计算实例分配给另一位数据科学家

尽管这是网页界面向导提供的一个很好的功能,但当你需要为多个数据科学家配置多个计算实例时,它的扩展性较差。因此,大多数情况下,管理员更喜欢通过ARM 模板部署计算实例。管理员可以通过该向导生成并下载模板,然后使用Azure CLI将其部署给多个用户,并将用户 ID 作为参数传递,正如你在第二章中所见,部署 Azure 机器学习工作区资源

到目前为止,你已经了解了如何配置计算实例。在下一节中,你将学习如何管理计算实例。

管理计算实例

一旦你至少配置了一个计算实例,管理 | 计算 | 计算实例界面将变成一个列表,显示工作区中可用的实例。默认情况下,列表会过滤,仅显示你可以使用的实例,也就是说那些你自己配置的或其他人代表你配置的实例:

图 4.18 – 计算实例列表

图 4.18 – 计算实例列表

从这里,你可以启动、停止、重启和删除计算实例。当你启动一个计算实例时,资源的状态会变为运行中,并且应用程序列会提供链接,打开该计算实例的终端,或者打开 Jupyter、JupyterLab、RStudio 和 VS Code 等第三方创作体验。

在你打开这些三种编辑体验之前,你必须接受一个重要的通知,关于你可以在这些环境中执行的代码,如下图所示:

图 4.19 – 关于你在 Azure ML Studio 执行代码的警告消息

图 4.19 – 关于你在 Azure ML Studio 执行代码的警告消息

你需要理解,如果你从互联网下载一个随机脚本,它可能包含恶意代码,可能会让其他人窃取数据或甚至访问你账户的令牌,这可能使他们能够代表你访问 Azure 资源。

JupyterLab 和 Jupyter 是非常流行的 Jupyter 笔记本创作体验、Python 脚本编辑以及访问终端执行各种命令的工具,如下图所示。当你点击打开这些编辑体验时,会打开一个新的浏览器标签页。如果你查看新标签页上的 URL,你会注意到它由计算实例的名称、该计算实例所在的区域以及后缀instances.azureml.ms组成。这就是为什么在前面一节中,配置计算实例时,当你配置计算实例时,必须选择一个在你所在 Azure 区域内唯一的名称的原因。

所有这些第三方创作体验都有着强大的社区支持,你可以在已经熟悉的情况下使用它们。然而,请注意,Azure ML 提供了作者 | 笔记本体验,这是基于 JupyterLab 的增强编辑体验,增加了像 IntelliSense 这样的功能,从第七章《Azure ML Python SDK》开始,你将使用到这些功能:

图 4.20 – JupyterLab 编辑体验

图 4.20 – JupyterLab 编辑体验

点击应用程序栏中的终端链接将打开一个新的浏览器标签页。你将被转到作者 | 笔记本部分。在这里,会打开一个基于 Web 的终端,允许你向计算实例发出命令:

图 4.21 – 通过浏览器获取终端访问

图 4.21 – 通过浏览器获取终端访问

当你不需要计算实例时,比如在周末,你可以停止它以避免产生费用。计算实例将转为已停止状态,且应用程序链接将被禁用。启动已停止的计算实例需要一些时间。

如果你已经完成了与计算实例的工作,例如项目的研究阶段已经结束,你可以删除它,以释放占用的 CPU 核心,这些核心会计入你订阅的配额。你可以通过点击菜单中相应的查看配额选项来查看当前的配额,如图 4.18所示。

现在,你可以停止你的计算实例。你将在数据漂移检测部分重新启动它:

图 4.22 – 已停止的计算实例

图 4.22 – 已停止的计算实例

在本节中,你学会了如何配置和管理计算实例,这些实例将为你提供必要的计算能力,用于编写笔记本和脚本,并可能执行小规模的训练和推理管道。在下一节中,你将学习如何配置计算集群,这是一种计算资源,能够根据需要进行扩展或缩减,以同时支持多个训练和推理管道。

计算集群

计算集群是一组相互连接的虚拟机,这些虚拟机可以根据任务队列的需要进行扩展或缩减。这意味着,集群在不需要时可以只有几个节点,甚至没有节点,从而避免产生不必要的费用;而在需要运行大量任务并行处理或执行分布式机器学习训练过程时,它也可以扩展到多个节点。

创建过程与配置计算实例非常相似。让我们来看看:

  1. 首先,点击计算集群标签页中的新建按钮,如图 4.23所示。图 4.23 – 创建新的计算集群

    图 4.23 – 创建新的计算集群

  2. 您会注意到,与计算实例相比,计算集群配置向导提供了一个额外的选项,称为虚拟机优先级,如下图所示。低优先级虚拟机利用您希望配置计算集群的 Azure 区域中的剩余容量。这些虚拟机的价格相比专用虚拟机大幅降低,但计算节点在您需要时可能无法提供,甚至可能在计划任务完成之前就被回收。这意味着,您可能需要等待较长时间才能分配到这样的虚拟机,而且在训练过程中某个步骤可能会中断执行。由于低优先级虚拟机具有这些特点,通常在您有一些对时间不敏感的任务,且这些任务由小的运行步骤组成,或者这些步骤能够自动保存其状态并在被驱逐后恢复执行时,您会使用这种类型的集群。为了本书的目的,您可以选择专用选项,以避免在分配计算节点时出现意外的长时间等待。

  3. 虚拟机类型选项中,选择GPU,并从从推荐选项中选择列表中选择最便宜的虚拟机大小,如图 4.24所示。

    重要提示

    默认情况下,免费试用订阅不允许您配置 GPU 计算。即使您更改为按需订阅,您仍然需要通过 Azure 门户提交请求以增加配额。如果遇到配额不足的问题,您可以选择基于 CPU 的计算,而不是基于 GPU 的计算。为了本书的目的,您无需使用基于 GPU 的集群。

    图 4.24 – 计算集群配置向导的第一页

    图 4.24 – 计算集群配置向导的第一页

  4. 单击下一步以继续进入向导的第二页:

  5. 在向导的第二页中,您需要指定一个集群名称。这个名称将在网页界面和代码中用于引用该集群,因此请确保选择一个能代表该集群用途的名称,例如 gpu-cluster图 4.25 – 计算集群配置向导的第二页

    图 4.25 – 计算集群配置向导的第二页

    您还可以调整节点的最小和最大数量,以及在集群缩减之前的空闲秒数。每次请求集群执行任务时,任务将添加到集群的调度器中。如果集群没有足够的节点来执行调度的任务,它将通过向集群添加计算节点来进行扩展。向集群添加节点需要一些时间,因为您需要分配虚拟机。因此,在调度任务完成后,集群不会立即释放虚拟机,而是可以等待定义的空闲时间,以防新的任务被调度。

    与计算实例类似,如果您希望远程连接到计算集群节点以排查作业执行问题,您可以 启用 SSH 访问。由于集群节点是临时的,向导允许您指定 管理员密码,如果您希望的话,而不是使用 SSH 公钥,如下图所示:

    图 4.26 – 计算集群允许您使用管理员密码而不是 SSH 公钥

    图 4.26 – 计算集群允许您使用管理员密码而不是 SSH 公钥

    高级设置 下,您可以找到 启用虚拟网络 选项,您在上一节查看计算实例时也看到了这个选项。除了这个选项,您还有一个选项是 为计算集群分配托管身份

    图 4.27 – 为计算集群分配托管身份

    图 4.27 – 为计算集群分配托管身份

    Azure 允许您为计算集群节点附加 Azure Active DirectoryAAD)身份,这样在这些虚拟机中执行的代码可以使用该身份访问 Azure 资源。托管身份消除了在脚本中存储凭据的需求。身份与特定的虚拟机关联,您的代码可以通过 Azure 实例元数据服务或 Python SDK 请求 AAD 访问令牌,无需密码,只要代码在该特定虚拟机中执行。

  6. 本书的目的下,您不需要在此修改任何选项。将集群命名为 gpu-cluster,然后点击 创建 来创建您的第一个零节点 GPU 基础计算集群:

图 4.28 – 您的第一个基于 GPU 的计算集群已准备好使用

图 4.28 – 您的第一个基于 GPU 的计算集群已准备好使用

请注意,在前面的截图中,计算集群已成功配置,但其中没有节点,这意味着它不会产生任何费用。您还可以在此列表中看到以下指标:

  • 空闲节点:这些是等待任务调度或在空闲时间过去后等待被释放的节点。

  • 忙碌节点:这些是当前正在执行任务的节点。

  • 未配置的节点:这些是尚未分配的节点,但如果计划任务的数量增加,它们可能会被分配。

    从此列表中,你可以删除集群,如果你不再需要它的话。

    如果你点击计算集群的名称,你将能够看到集群的详细信息,如下图所示。从此视图,你可以编辑最小和最大节点数、集群缩减前的空闲秒数,并更改之前配置的托管身份分配方式。事实上,数据科学团队通常会在早晨修改他们预定义的计算集群配置,以便确保集群中至少有一个节点,这样他们就不必等待第一个节点分配。当一天结束时,他们会将设置改为零,以节省成本:

图 4.29 – 计算集群的详细信息,展示你可以编辑其配置的位置

图 4.29 – 计算集群的详细信息,展示你可以编辑其配置的位置

在这一部分,你学习了如何配置计算集群。这些集群用于执行训练任务和批量推理。在下一部分,你将学习如何配置Azure Kubernetes 服务AKS),它允许你在大规模上执行实时推理。

推理集群

Kubernetes 是一个便携、可扩展的开源平台,用于管理容器化的工作负载和服务。由于其能够自动扩展并能从故障中自动恢复,它已被广泛用于将各种应用投入生产环境,从 Web 应用到模型推理 REST API。Azure Kubernetes 服务AKS)是 Azure 中的 Kubernetes 集群的托管版本,一项让你专注于工作负载并让 Azure 管理集群操作部分(例如其主节点)的服务。

如果你不熟悉 AKS,不用担心——下面的图表提供了涉及组件的高级概览。简而言之,你可以配置节点池,即一组配置相同的虚拟机;例如,配置有 GPU 卡的虚拟机。这些池可以包含一个节点(或更多节点),节点即为虚拟机。在每个节点内,你可以托管一个或多个Pod。每个 Pod 包含一对Docker 镜像,这些镜像组成一个应用单元,其中一个镜像可能是你想要投入运营的模型。每个 Pod 可以在多个节点中进行复制,既可以是为了应对更高的负载,也可以是在某个节点出现故障时增加容错性:

图 4.30 – AKS 概念的高级概览,展示 Pod X 在两个节点中复制

图 4.30 – AKS 概念的高级概览,展示 Pod X 在两个节点中复制

在 Azure ML Studio 中,你可以创建或将现有的 AKS 集群附加到你的工作区。你不需要为本书的目的创建 AKS 集群。让我们开始吧:

  1. 创建向导可以通过点击新建按钮,在推理集群标签页中启动,如图 4.31所示:图 4.31 – 创建或将 AKS 集群附加到 Azure ML 工作区

    图 4.31 – 创建或将 AKS 集群附加到 Azure ML 工作区

    重要说明

    当您配置 AKS 集群时,一个新的资源组将在您的 Azure 订阅中创建,托管 AKS 工作所需的所有组件。这需要在订阅级别的额外权限。如果您无法创建资源组,AKS 集群配置将失败。

  2. 在向导的第一步中,您可以选择附加一个现有的 AKS 集群或创建一个新的集群。如果选择创建一个新的集群,您将需要指定希望 AKS 集群部署的 Azure 区域。您还需要指定节点池的虚拟机大小,类似于您部署计算实例时所做的操作:图 4.32 – 配置推理 AKS 集群的步骤 1

    图 4.32 – 配置推理 AKS 集群的步骤 1

  3. 点击下一步将带您进入设置页面,在此页面中,您需要指定 AKS 集群的名称。同时,您还需要指定集群的用途。如果这是一个生产集群,则集群中的虚拟 CPU 数量必须大于 12;这意味着如果您选择了 4 核虚拟机大小,您将需要至少三个节点才能配置一个生产就绪的 AKS 集群。如果此集群用于开发和测试,您只需配置一个节点即可。

  4. 除了节点池的名称和节点数外,您还可以配置集群的网络选项和用于保护与应用程序连接的 SSL 证书,如果您希望通过 HTTPS 端点公开它们。为了本书的目的,您无需修改这些选项:图 4.33 – 配置推理 AKS 集群的步骤 2

    图 4.33 – 配置推理 AKS 集群的步骤 2

  5. 一旦集群创建完成,您将能够通过以下截图所示的列表删除或将其从工作区中分离:

图 4.34 – AKS 推理集群列表

图 4.34 – AKS 推理集群列表

重要说明

AKS 是部署实时端点的生产就绪方式。在考试中,当被问到将生产负载部署在哪里时,AKS 应该是正确答案。尽管如此,由于 AKS 集群是一种昂贵的资源,本书的示例不会使用它。如果您使用的是免费订阅,您可能没有足够的核心配额来配置一个。如果您配置了一个,请确保关注成本,以免用完信用额度。

在本节中,你了解了如何使用 Azure ML 帮助你连接或配置 AKS 集群,以便托管生产实时推理端点。在下一节中,你将学习如何将现有的计算资源附加到你的工作区。

附加的计算资源

如果你已经配置了计算资源,且不一定是在你部署 Azure ML 工作区的订阅中,你可以将它们附加到你的工作区。附加这些资源可以让你重新利用它们,特别是在它们未被充分利用的情况下。一种常见的情况是,一个部门拥有一个基于 Ubuntu 的 数据科学虚拟机 (DSVM),可能每天 24 小时、每周 7 天都在运行,以服务于一个遗留的 Web 应用程序。你可以通过将其附加到工作区并在实验中引用它来重用这个资源,执行各种任务,就像你引用计算集群来执行任务一样。

工作室体验允许你附加多种类型的计算资源,包括以下流行目标:

  • 虚拟机:你可以附加现有的基于 Ubuntu 的虚拟机,这些虚拟机通过互联网公开可访问。这个选项包括你可能已经拥有的 DSVM。

  • Azure DatabricksHDInsights:这些选项允许你将现有的基于 Apache Spark 的计算资源连接到你的工作区。

  • Azure Data Factory:Azure Data Factory 资源允许你从一个数据源执行复制操作到另一个数据源。例如,你可以使用该资源将数据从存储帐户复制到 SQL 数据库。Azure Data Factory 目前仅通过 Azure ML SDK 支持,而不支持通过工作室体验。

对于 DP100 考试而言,你无需附加任何资源。以下截图展示了你如何从工作室体验中启动附加向导:

图 4.35 – 将现有计算资源附加到你的工作区

图 4.35 – 将现有计算资源附加到你的工作区

在本节中,你了解了如何配置和附加计算资源到你的 Azure ML 工作区。这使得你可以在数据探索、模型训练和模型推理阶段执行代码。在下一节中,你将学习如何配置与各种数据源的连接,这将使你能够访问数据。

连接到数据存储

数据存储是存放你数据的引擎,并为任何有权限的人提供访问权限。在大多数你在互联网上看到的 Python 示例中,都会有一个连接字符串,其中包含连接到数据库或 Blob 存储的凭证。这个技术有几个缺点:

  • 存储在这些脚本中的凭证被视为安全违规行为,通过将脚本发布到公共存储库(如 GitHub)可能会意外暴露你受保护的数据集。

  • 当凭据发生变化时,你需要手动更新所有脚本。

Azure ML 允许你拥有一个集中式的位置,在那里你可以定义与各种存储的连接属性。你的凭据作为机密安全存储在工作区关联的密钥库中。在你的脚本中,你通过其名称引用数据存储,并可以访问其数据,而无需指定凭据。如果某个时刻,数据存储的凭据发生变化,你可以在中央位置更新它们,所有的脚本和管道将继续正常工作。

你可以通过导航到工作室的管理 | 数据存储部分来查看所有注册的数据存储:

图 4.36 – 工作区中已注册数据存储的列表

图 4.36 – 工作区中已注册数据存储的列表

请注意,默认情况下,你已经注册了两个数据存储。默认的那个,名为workspaceblobstore,是默认的 Blob 存储,用于存储所有的管道指标和工件。你的工作区需要有一个默认的数据存储。正如你将在第七章《Azure ML Python SDK》中看到的,你甚至可以通过 Python SDK 非常方便地引用该存储。另一个存储,名为workspacefilestore,是一个文件共享数据存储,你可以将其挂载到本地计算机并上传文件。

从此列表中,你可以执行以下操作:

  • 更新数据存储的凭据:你需要点击数据存储的名称,查看其注册详情。从那里,你可以点击更新凭据来指定更新的值,或者更改身份验证类型,这些内容将在下一节中看到。

  • 注销数据存储:你可以注销任何未标记为默认数据存储的数据存储。

  • 设置为默认数据存储:将默认数据存储更改为你从列表中选择的存储。

最后,从这个列表中,你可以创建一个新的数据存储注册,这是启动新的数据存储向导的操作,如下图所示:

图 4.37 – 新的数据存储向导

图 4.37 – 新的数据存储向导

在这里,你需要在 Azure ML 工作区中指定一个唯一的数据存储名称。你必须这样做,以便在脚本和工作室体验的各个组件中引用该存储。接下来,你需要选择数据存储类型。Azure ML 工作区支持几种 Azure 本地数据存储,这些内容将在下一节中探讨。

数据存储类型

Azure ML 支持两类数据存储:基于文件的存储,例如 Blob 存储、文件共享和数据湖存储,以及关系型数据库,例如 Azure SQL 和 Azure PostgreSQL。

当前支持的数据存储如下面的图示所示:

图 4.38 – Azure ML 支持的数据存储

图 4.38 – Azure ML 支持的数据存储

推荐使用基于Azure Blob Storage的数据存储。这些存储是最具成本效益的存储。它们提供多个层级,例如更昂贵的高级存储,它提供更高的吞吐速度,这可以减少处理大量数据时的训练时间。

另一方面,Azure Data Lake Storage Gen 2Azure Blob Storage的基础上,增加了层次命名空间。这一功能使得数据湖可以在文件夹级别分配访问权限。大型企业通常会按照不同的区域结构来组织数据湖,存储不同的数据。每个区域都有自己的访问控制列表ACL),为特定的用户组提供权限。这意味着你可能能够看到某个文件夹的内容,而看不到另一个文件夹的内容,而在Azure Blob Storage中,一旦你获得了容器的访问权限,就可以看到该容器中的所有数据。

如果你的数据存储不被 Azure ML 开箱即用地支持,你可以通过Azure Data Factory的复制工具轻松将数据复制到Azure Blob StorageAzure Data Lake Storage Gen 2Azure Data Factory 允许你从几乎任何地方复制数据,即使数据存储在本地数据库中,如下图所示:

图 4.39 – 使用 Azure Data Factory 和自托管集成运行时将本地数据复制到 Azure ML 支持的数据存储

图 4.39 – 使用 Azure Data Factory 和自托管集成运行时将本地数据复制到 Azure ML 支持的数据存储

重要说明

附加计算部分,你看到了你可以附加一个DataTransferStep。从本地网络复制数据也可以在同一个 ADF 中完成,但你需要在 ADF 中编写、执行和监控数据拉取管道。

本节介绍了 Azure ML 支持的各种数据存储类型。在下一节中,你将了解这些数据存储支持的各种身份验证方法。

数据存储安全性考虑

根据数据存储类型,你需要为其注册到 Azure ML 工作区时指定不同的凭据。对于 Azure Blob 和 Azure 文件共享数据存储,你可以使用以下凭据:

  • 账户密钥:这授予对整个 Azure 存储账户的访问权限。

  • 共享访问签名SAS令牌:这是一种更加细粒度的权限分配方式,允许你为存储账户的各种服务分配权限。使用账户密钥,你可以生成一个 SAS 令牌,使其只能访问特定的 blob 容器,并且只能在有限的时间内使用。

对于 Azure Data Lake Storage 数据存储,鉴于其高级安全功能,您需要提供一个tenant_id,该实体已注册并具有唯一 ID(称为client_id)。此身份拥有一个密码(称为client_secret),它使得您的代码能够模拟该身份访问数据存储。

对于关系数据库数据存储,您需要指定数据库的名称、服务器的名称和服务器端口进行连接。对于凭证,您可以提供服务主体,如果数据存储支持此功能,或者提供必要的SQL 身份验证凭证,后者包括数据库用户 ID 和密码。

一些数据存储允许您使用工作区的托管身份进行数据预览和分析。此选项会将分配给工作区的系统分配托管身份作为读取者,添加到特定资源中,从而允许工作区在工作室环境中加载数据预览。此选项可在数据存储注册页面上找到,如下图所示:

图 4.40 – 授予工作区的托管身份访问权限

图 4.40 – 授予工作区的托管身份访问权限

到目前为止,您已学习了如何在 Azure ML 工作区中注册各种数据存储。在下一节中,您将学习如何利用这些注册信息来定义数据集。

使用数据集

在前面的章节中,您在工作室的管理部分配置了计算和数据存储资源。配置好这些基础设施后,您可以开始将数据导入到注册的数据存储中,并在工作室的资产部分注册数据集:

图 4.41 – 在 Azure ML Studio 中的资产部分的数据集

图 4.41 – 在 Azure ML Studio 中的资产部分的数据集

数据集是您用于训练和推理的基础数据之上的抽象层。它包含指向物理数据位置的引用,并提供一系列元数据,帮助您理解其形状和统计特性。当您想要访问数据集时,可以通过名称引用它,且无需担心凭证或确切的文件路径。此外,所有在同一工作区的 data scientists 都可以访问相同的数据集,从而允许他们在相同数据上并行进行实验。

数据集有两种类型——基于文件的和基于表格的。文件数据集引用数据存储中的文件列表。例如,如果你正在构建一个计算机视觉模型,你需要图像,这些图像可以作为FileDataset下载或挂载到计算资源上。表格数据集表示存储在文件型数据存储或关系型数据库数据存储中的表格数据。例如,你可以引用包含TabularDataset结构的几个文件夹,而不需要解析物理文件。

数据集的另一个特点是你可以通过版本快照它们的属性和元数据。假设你有一个遵循weather/<year>/<month>/模式的文件夹结构。例如,你会发现 2021 年 1 月的天气测量数据存储在weather/2021/01/measurements.parquet下。随着时间的推移,你会获得越来越多的文件夹,每个文件夹下面都有一个文件。为了重现你的训练结果,你可能希望引用一个只包含到 2021 年 1 月为止文件的数据集。这正是数据集版本控制的用武之地。在训练模型时,你注册一个数据集版本,该版本包含你用于训练的所有文件。稍后,你可以引用该数据集并请求它的特定版本,从而获得对当时可用的所有文件的引用。

重要说明

数据集版本复制底层数据。它们只存储对实际文件的引用以及你将在接下来的章节中阅读到的数据集元数据。这意味着,如果你更改了文件的内容而不是添加新文件,数据集版本将不会加载相同的数据。

注册数据集

你可以从多个来源注册数据集,如下图所示,包括你在连接数据存储部分学到的如何注册的存储库:

图 4.42 – 注册数据集的可能选项

图 4.42 – 注册数据集的可能选项

为了更好地理解数据集注册过程,我们将注册两个托管在 Web 上的表格数据集。这些数据集每个都包含一个parquet文件。我们将在本章后续部分使用这两个数据集来了解数据漂移检测功能。让我们开始吧:

  1. 从前面的截图中选择从 Web 文件菜单项,开始从 Web 文件创建数据集向导。

  2. 在向导的第一页,提供以下信息:

    • survey-drift-base

    • Tabular

  3. 点击下一步图 4.43 – 数据集注册向导的第一步

    图 4.43 – 数据集注册向导的第一步

  4. 向导将解析文件并确定文件类型和数据集的模式。你需要通过点击下一步来验证选择。请注意,向导支持多种文件格式,如下图所示:图 4.44 – 数据集注册向导的第二步

    图 4.44 – 数据集注册向导的第二步

  5. 在下一步骤中,你可以定义有关模式的高级选项。对于基准数据集,保持默认选项不变。点击下一步,你将进入确认步骤。

  6. 在此步骤中,你可以查看前面步骤中的选择,还可以安排你的首个数据科学分析任务——数据集概况分析。此过程将生成你将在下一部分中探索的概况。启用此选项,并选择你在前一部分中配置的gpu-cluster,如下图所示:

    重要提示

    选择用于概况分析的计算资源选项中,你可以从你在计算实例计算集群部分配置的计算实例和计算集群中进行选择。选择计算集群将强制集群从零个节点扩展到一个节点,分析数据集,然后再缩减回零个节点。如果你愿意,可以导航到管理 | 计算部分,通过点击计算集群的名称来观察这一扩展过程。如果你选择计算实例而不是计算集群,则任务将被安排,并将在计算实例启动时执行。

图 4.45 – 数据集注册过程的最后一步

图 4.45 – 数据集注册过程的最后一步

你需要再注册一个数据集。此过程几乎相同,只不过这次你将数据集标记为时间序列数据集:

  1. 点击创建数据集并选择从网页文件,如下图所示:图 4.46 – 数据集列表中的创建数据集菜单

    图 4.46 – 数据集列表中的创建数据集菜单

  2. 按照之前的步骤操作,输入以下信息:

    • survey-drift-target
  3. 在模式步骤中,请确保从inference_date列的Properties部分选择时间戳Timestamp),如下图所示。此选项将此表格数据集标记为时间序列数据集,允许你执行额外的分析,正如你将在数据漂移检测部分看到的那样:图 4.47 – 配置一个表格数据集,使其成为时间序列数据集

    图 4.47 – 配置一个表格数据集,使其成为时间序列数据集

  4. 安排数据概况分析并完成数据集注册过程。

    重要提示

    如果你跟随教程,你可能会注意到,对于 year=2021/month=05/day=01/data.parquet,你可以通过该路径模式创建一个虚拟列,并将其定义为分区时间戳。这样可以提升时间序列功能的重要性,并允许你通过有选择性地读取所需文件来加载特定日期的数据。

你应该能够看到两个已注册的数据集,如下图所示:

图 4.48 – 在 Azure ML 工作区注册的数据集列表

图 4.48 – 在 Azure ML 工作区注册的数据集列表

在此视图中,你可以选择一个数据集,然后点击取消注册按钮来移除注册。点击数据集后,你可以查看有关该数据集的更多详细信息,包括你在数据集上执行的分析,这些内容将在下一节中显示。

探索数据集

在数据集列表中,点击survey-drift-target数据集以查看其详细信息。在第一个标签页详情中,你可以修改数据集的描述,并指定与数据集相关联的标签。标签是名称-值对。在下面的截图中,你可以看到我们将survey指定为experiment标签的值:

图 4.49 – 显示与特定数据集相关的所有元数据的数据显示

图 4.49 – 显示与特定数据集相关的所有元数据的数据显示

消费标签页中,你可以复制你将在第七章中使用的 Python SDK 代码,以便访问数据集:

图 4.50 – 消耗一个代码片段以访问数据集

图 4.50 – 消耗一个代码片段以访问数据集

探索标签页中,你将能够预览数据集中包含的样本数据,正如你在注册过程中所看到的:

图 4.51 – 预览数据集的样本

图 4.51 – 预览数据集的样本

如果你点击分析标签页,你将能够查看数据集的统计分析,正如下图所示:

图 4.52 – 数据集的统计分析

图 4.52 – 数据集的统计分析

重要提示

如果你的数据集包含少于 10,000 行,系统会自动为你执行数据分析,而无需你手动调度数据集的处理过程。如果数据集包含超过 10,000 行,Azure ML 会对前 10,000 行进行分析,并显示一条警告消息,提示你调度完整的分析过程,你可以通过点击菜单中的生成分析按钮来执行此操作。

最后,在模型标签下,你可以看到与此数据集相关的模型,这是你在第五章让机器进行模型训练时,将注册并部署为 Web 服务的最佳模型。

注册了数据集后,你可以为该数据集配置周期性的漂移监控,这是你将在下一节中学习到的内容。

数据漂移检测

数据漂移检测是一种技术,允许你将时间序列数据集与参考数据集进行比较,然后检查你比较的特征的统计属性是否发生了显著变化。例如,假设你训练了一个 ML 模型,预测某人是否会参与调查,基于他们的年龄。你使用了survey-drift-base数据集来训练该模型。下图展示了一个密度曲线,显示了训练数据集中年龄的分布:

图 4.53 – 训练数据集中年龄特征的负偏斜单峰分布

图 4.53 – 训练数据集中年龄特征的负偏斜单峰分布

当你将模型投入生产时,你每周跟踪它做出的推断,并将此信息记录在之前注册的survey-drift-target数据集中。该数据集包含了你在 2020 年初的前两周进行的推断。数据漂移检测能够帮助你发现输入特征的分布是否随着时间变化。我们来看看:

  1. 导航到资产 | 数据集 | 数据集监控,点击创建按钮以启动数据集监控向导:图 4.54 – 创建新的数据集监控

    图 4.54 – 创建新的数据集监控

  2. 在目标数据集上,你将看到所有已注册的时间序列数据集,这些数据集是你希望监控数据漂移的对象。这是你的模型在生产环境中所做的推断。选择survey-drift-target (Version:1)并点击下一步图 4.55 – 数据漂移监控配置的第一步

    图 4.55 – 数据漂移监控配置的第一步

  3. 在下一页中,你需要选择参考点。这可以是时间序列表格数据集中的某个特定时间点,或者是一个特定的数据集。在你的情况下,选择survey-drift-base (Version:1)数据集,这是用于训练 ML 模型的数据集:图 4.56 – 在数据漂移监控配置中选择基线数据集

    图 4.56 – 在数据漂移监控配置中选择基线数据集

  4. 在向导的最后一步,你需要定义以下信息:

    • survey-drift-monitor

    • 特征:选择两个数据集之间一个或多个共同特征,以监控它们的分布情况以及是否存在数据漂移。在此案例中,两个数据集之间唯一的共同特征是年龄特征。

    • 计算目标:将启动和停止以执行分析的集群。

    • 频率:频率指定检查目标数据是否有漂移的时间间隔。一旦监控器创建,无法更改此属性。您可以选择按天、按周或按月进行。请记住,每个时间间隔至少需要 50 个样本才能进行数据漂移分析。这意味着如果每天少于 50 行数据,您不能将其作为频率,应该选择按周或按月进行。

    • 延迟:通常会在实际对行进行评分和刷新目标数据集之间有一个延迟。在此字段中,您需要指定在假设目标数据集已经获得最新记录之前的等待时间;然后,监控器就可以执行数据漂移分析。

    • 电子邮件地址:如果数据集的漂移超过了阈值参数所指定的范围,邮件将发送至此地址。

  5. 本书中,您可以禁用计划,如下截图所示。您将手动运行数据漂移分析。

  6. 点击创建按钮以创建监控器:图 4.57 – 数据漂移监控器设置

    图 4.57 – 数据漂移监控器设置

  7. 从监控器列表中点击您创建的新监控器名称:

图 4.58 – 数据漂移监控器列表

图 4.58 – 数据漂移监控器列表

数据漂移监控器旨在根据计划对新数据进行分析。在您的情况下,您想分析目标数据集中的现有数据。让我们来看看:

  1. 点击分析现有数据按钮,这将显示以下截图中的回填向导:图 4.59 – 手动启动对过去日期的分析

    图 4.59 – 手动启动对过去日期的分析

  2. 选择从 2019 年 12 月 31 日到 2020 年 1 月 15 日。这是包含目标数据集所有记录的时间范围。

  3. 选择将进行分析的计算集群。

  4. 点击提交

一旦分析完成(这个过程需要一些时间),您将能够看到数据漂移的结果,结果表明我们的数据集观察到了大规模的数据漂移。请注意,摘要指的是最新的推理结果,这些推理是在 2020 年 1 月 5 日完成的。您可以通过点击对应日期的图表手动选择之前的时间段:

图 4.60 – 基础数据集与目标数据集之间检测到的数据漂移

图 4.60 – 基础数据集与目标数据集之间检测到的数据漂移

如果你向下滚动到特征分布部分,你将能够清楚地看到年龄特征的分布漂移。这表明模型正在对一个与其训练数据集特征不同的群体进行推理。这是一个很好的指示,表明你可能需要重新训练模型,以便使其与新的特征分布保持同步。

图 4.61 – 基准线是一个负偏态分布,而最新的推断遵循一个正偏态分布

图 4.61 – 基准线是一个负偏态分布,而最新的推断遵循一个正偏态分布

在这一部分,你学习了如何配置数据漂移检测,这一过程是通过将你在生产环境中观察到的数据与用于训练模型的数据集进行比较来完成的。这是一个强大的功能,它可以帮助你判断是否需要使用更新的数据重新训练模型,尤其是当特征分布随时间发生变化或漂移时。

总结

在这一章中,你学习了如何为你的 Azure ML 工作区提供和附加计算资源。你还学会了如何注册各种数据存储,以便安全地访问数据。最后,你探索了 Azure ML Studio 的数据集注册功能,它使你能够轻松访问用于实验的数据。注册数据集后,你可以配置数据漂移监控器,当特征分布随时间变化时,它会提醒你,这可能表明在该数据集上训练的机器学习模型需要重新训练。现在你应该已经能够舒适地配置你的 Azure ML 工作区,这是 DP-100 认证中考察的关键技能之一。

在下一章中,你将学习如何利用你在工作区中注册的数据集进行自动化机器学习(Auto ML)分析,这一过程将在你提供的计算集群上运行多个机器学习实验,以检测适合你数据集的最佳算法。

问题

在每一章中,你会找到一些问题,以便测试你对本章内容的理解:

  1. 一个拥有 8 核心和 56 GB 内存的计算实例上最多可以有多少个数据科学家同时工作?

    a. 只有一个。

    b. 最多两个。

    c. 最多五个。

    d. 只要不耗尽计算资源,人数不限。

  2. 你需要提供哪种类型的凭证才能访问 Gen 1 或 Gen 2 的数据湖存储?

    a. 个人访问令牌PAT

    b. 服务主体的客户端 ID 和密钥

    c. 你的个人 AAD 用户凭证

    d. 不需要凭证

  3. 以下哪种 Azure 工具可以帮助你协调将数据从本地环境迁移的工作?

    a. Blob 存储

    b. Azure Active Directory

    c. Azure 数据工厂

    d. Azure ML 工作区

进一步阅读

本节提供了一个有用的网络资源列表,帮助你增强对本章讨论主题的理解和知识:

第二部分:无需编码的数据科学实验

Azure 机器学习工作室提供各种无需编码/低代码向导和设计器,帮助高级用户进行端到端的数据科学实验。经验丰富的数据科学家和机器学习工程师也可以利用这些工具启动项目、验证假设、了解在特定数据集上哪个模型表现最佳,并设计数据清洗流程,而无需编写任何代码。在本节中,您将学习如何通过 Azure ML Studio 提供的网页设计器和向导运行数据科学实验。

本节包括以下章节:

  • 第五章**,让机器来进行模型训练

  • 第六章**,视觉模型训练与发布

第五章:第五章:让机器来训练模型

在本章中,你将创建你的第一个 自动化机器学习自动化 MLAutoML)实验。AutoML 是指尝试多种建模技术并选择在你指定的训练数据集上产生最佳预测结果的模型的过程。首先,你将浏览 Azure 机器学习工作室 Web 体验中的 AutoML 向导,并了解需要配置的不同选项。然后,你将学习如何监控 AutoML 实验的进度,以及如何将最佳模型作为 Web 服务部署到 Azure 容器实例ACI)中,从而能够进行实时推断。

通过坐在电脑前并带着这本书,你可以顺利完成本章内容。通过结合使用你的 Azure 订阅和本书,你可以开始你的 AutoML 之旅。

在本章中,我们将覆盖以下主要内容:

  • 配置 AutoML 实验

  • 监控实验的执行

  • 将最佳模型部署为 Web 服务

技术要求

你需要访问 Azure 订阅。在该订阅中,你需要一个 packt-azureml-rg。你需要拥有 ContributorOwner 权限的 packt-learning-mlw,如 第二章 中所述,部署 Azure 机器学习工作区资源

配置 AutoML 实验

如果你被要求训练一个模型来对数据集进行预测,你需要做几件事,包括数据集的归一化、将数据集拆分为训练数据和验证数据、运行多个实验以了解哪种算法在数据集上的表现最佳,然后对最佳模型进行微调。自动化机器学习通过完全自动化耗时的迭代任务,缩短了这个过程。它允许所有用户,从普通 PC 用户到经验丰富的数据科学家,都可以针对目标数据集构建多个机器学习模型,并根据你选择的度量标准选择表现最好的模型。

该过程包括以下步骤:

  1. 准备实验:选择你将用于训练的数据集,选择你要预测的列,并配置实验的参数。这是你将在本节中阅读到的配置阶段。

  2. 数据保护措施:这是执行实验的第一步。它对提供的训练数据集进行基本的数据保护措施。AutoML 尝试识别数据中的潜在问题;例如,你要预测的列中所有的训练数据必须具有相同的值。

  3. 训练多个模型:训练多种数据规范化和算法的组合,以找到最佳模型,从而优化(最大化或最小化)所需的度量标准。这个过程将一直持续,直到满足退出标准:时间限制或指定的模型性能目标。

  4. 创建集成模型:在这里,你训练一个模型,它结合了到目前为止训练的最佳模型的结果,并生成一个可能改进的推断。

  5. 选择最佳模型:根据你指定的度量标准,选择最佳模型。

Azure 机器学习提供了一个基于网页的向导,允许你配置这样的实验。在第三章中,Azure 机器学习工作室组件,你探讨了Azure 机器学习工作室网页体验。

在这一章中,你将创建一个自动化机器学习分类模型,该模型将预测一个客户是否会流失。这个模型能够预测客户是否会继续成为忠实客户,或者他们是否会终止他们的活动手机合同。你将使用来自一个虚构电信公司的虚构数据集。数据集显示了每个客户与公司合作的时长以及他们的活动订阅使用情况。让我们开始吧:

  1. 要开始 AutoML 实验,你需要打开浏览器并导航到 Azure 机器学习工作室。你将进入首页,如下图所示:图 5.1 – Azure 机器学习工作室首页

    图 5.1 – Azure 机器学习工作室首页

  2. 在 Azure 机器学习工作室的首页上,通过点击自动化机器学习下方的立即开始按钮,进入作者 | 自动化机器学习部分,如前面截图所示。这将打开自动化机器学习首页,如下图所示:图 5.2 – 自动化机器学习首页

    图 5.2 – 自动化机器学习首页

    在这个首页上,你可以找到最近执行的自动化机器学习实验。由于这是你第一次使用这个工作区,你应该不会看到任何运行记录。

  3. 通过点击新建自动化机器学习运行按钮,你将启动创建新自动化机器学习向导,如下所示:

图 5.3 – 启动自动化机器学习向导

图 5.3 – 启动自动化机器学习向导

在向导的第一步,名为选择数据集,你可以选择一个现有数据集或创建一个新的数据集。从这个列表中,你将能够看到在第四章中注册的两个数据集,配置工作区。你不需要这些数据集。在下一节中,你将学习如何创建一个新的数据集,以便用于即将执行的自动化机器学习实验。

注册数据集

自动化机器学习向导的选择数据集步骤中,你可以注册一个新的数据集,用于 AutoML 实验。按照以下步骤注册虚构的客户流失数据集:

  1. 点击屏幕顶部的创建数据集

  2. 从出现的下拉菜单中选择来自网页文件。这将启动从网页文件创建数据集向导,见下图。

  3. 向导的第一页(churn-dataset)。

    c) 表格型。这是一个无法更改的选项,因为 AutoML 目前只支持表格型数据集。

    d) 用于训练预测客户流失模型的数据集

    图 5.4 – 从网页文件创建数据集时的基本信息

    图 5.4 – 从网页文件创建数据集时的基本信息

  4. 填写完所有内容后,点击下一步。下载和解析文件需要一段时间。向导将转到设置和预览屏幕:图 5.5 – 从网页文件创建数据集向导的设置和预览屏幕

    图 5.5 – 从网页文件创建数据集向导的设置和预览屏幕

  5. 前面截图中显示的步骤提供了演示数据集的重要信息。样本文件的文件格式被自动检测为Parquet格式。如果需要,你可以修改选择。

    演示数据集包含七列:

    • ld是一个顺序记录号,不属于原始 Parquet 文件。AutoML 生成此序列号,以便你验证预览窗口中看到的数据。此列将不包含在注册数据集中。

    • id是一个字符串,唯一标识数据集中的每个客户。

    • customer_tenure是一个整数值,告诉我们每个客户在虚构的电信公司服务了多长时间。该值表示月份。

    • product_tenure是一个整数值,告诉我们客户当前活跃订阅的时长,单位为月。

    • activity_last_6_month告诉我们客户在过去 6 个月里通话的小时数。

    • activity_last_12_month告诉我们客户在过去 12 个月里通话的小时数。

    • churned是一个标志,告诉我们客户是否续订了订阅或终止了活跃的合同。这是你将要预测的列。

      从这个虚构的数据集中,构建你所尝试的分类模型的最相关特征是customer_tenureproduct_tenureactivity_last_6_monthactivity_last_12_monthchurned列是你试图构建的模型的目标id列允许你将模型的预测结果与可能流失的实际客户关联。

  6. 点击Date作为列的类型,你可以选择此列是否为时间戳,这将使数据集标记为时间序列数据集。将Date作为列的类型后,你可以定义用于解析特定列的日期模式。例如,你可以使用%Y-%m-%d来指定日期的存储格式为年-月-日。

  7. 完成探索向导的模式屏幕后,按下下一步。向导的确认详情页面提供了你想要在工作区中注册的新数据集的概览,如下所示:图 5.7 – 确认详情页面

    图 5.7 – 确认详情页面

    此页面总结了你在第四章 配置工作区节中阅读的数据集信息。如果你选择了创建后配置此数据集复选框,你可以选择一个计算目标来生成新创建的数据集的配置文件。由于该数据集仅有 6,720 行,Azure ML 会自动为你提供完整的配置文件,因此无需手动生成。

  8. 点击创建按钮以完成向导。

现在你已经注册了churn-dataset,可以继续进行 AutoML 向导,在此步骤中,你将选择新注册的数据集、配置实验参数并启动 AutoML 过程,这将在下一节进行。

返回到 AutoML 向导

现在你已经创建了churn-dataset,可以继续进行 AutoML 向导。向导包含三个步骤,如下图所示:

图 5.8 – AutoML 向导步骤

图 5.8 – AutoML 向导步骤

让我们开始步骤吧!

  1. 首先,选择在上一节注册数据集中创建的churn-dataset,然后点击下一步,如图所示:图 5.9 – 创建新的自动化 ML 运行向导的选择数据集步骤

    图 5.9 – 创建新自动化 ML 运行向导的选择数据集步骤

  2. churn-automl-experiment中,选择churned列。根据目标列的类型,向导将自动选择该列的最佳任务,如你将在下一个向导步骤中看到的。

  3. 这里是gpu-cluster,你在第四章 配置工作区节中创建的集群。如果你在工作区中没有注册集群,可以使用计算实例,或者通过点击gpu-cluster启动专用向导。默认情况下,免费试用订阅不允许配置 GPU 计算资源。对于此实验,你可以选择基于 CPU 的集群,而非基于 GPU 的集群。

  4. 配置运行详情后,点击下一步按钮。

  5. 向导的下一页是选择任务和设置页面,如下图所示:图 5.11 – 创建新的自动化机器学习运行向导 – 选择任务类型

    图 5.11 – 创建新的自动化机器学习运行向导 – 选择任务类型

    在此步骤中,你可以配置以下内容:

    a) 选择任务类型:AutoML 当前支持三种类型的任务:

    • 分类:生成的模型可以预测记录所属的类别。类别可以是任何东西,例如是或否的布尔值,或者蓝色、绿色或黄色的颜色值。在我们的例子中,你正在尝试预测客户是否会流失,这个问题可以通过“是”或“否”来回答。

    • 回归:当你想预测一个数值时,比如公寓的价格或糖尿病的疾病水平,可以使用回归模型。我们将在第八章使用 Python 代码进行实验中详细讨论。

    • 时间序列预测:通常使用这种类型的模型来预测时间序列值,比如股票的价格,同时考虑值随时间的变化。这种类型的模型是回归模型的一个专项扩展。这意味着所有回归模型都可以使用,但也有一些更专业的算法,比如 Facebook 的Prophet算法或自回归积分滑动平均ARIMA)技术。

    根据你选择的目标列,向导将自动猜测你要执行的任务。在我们的例子中,它选择了分类

    b) 查看额外的配置设置:根据你选择的任务类型,你可以配置各种设置,包括用于评估模型的目标指标以及终止模型搜索的退出标准。根据任务类型的不同,向导页面上的选项会有所变化。你可以在下图中看到一些选项。你将在步骤 5中访问这一部分:

    图 5.12 – 根据选择的任务类型配置设置

    图 5.12 – 根据选择的任务类型配置设置

    c) 查看特征化设置:这允许你配置与模型预测相关的特征操作。在此部分,你可以排除一些特征,比如行唯一 ID 或无关信息,以加快训练过程并减小最终模型的大小。你还可以指定每个特征的类型和插补函数,后者负责处理数据集中的缺失值。你将在步骤 6中访问此部分。

  6. 除非有理由修改,否则通常可以点击auto。默认情况下,如果行数少于 1,000,则使用 10 折交叉验证;如果行数在 1,000 和 20,000 之间,则使用 3 折交叉验证;如果行数超过 20,000,则数据集会被划分为 90%的训练数据和 10%的验证数据。

  7. 0.5,即半小时或 30 分钟。你可以保留其余选项不变,如前面的截图所示。点击保存,返回到你在步骤 4中看到的选择任务类型页面。

  8. 点击查看特征化设置,将打开特征化屏幕,如下所示:图 5.14 – 创建 AutoML 向导中的特征化视图

    图 5.14 – 创建 AutoML 向导中的特征化视图

    在此屏幕上,你可以定义影响训练过程数据准备阶段的操作。可以配置以下选项:

    • 包含:你可以排除不应被算法考虑的列。目标列无法排除。

    • 特征类型:默认情况下,选择了自动值,它会自动检测数据集中每一列的类型。类型可以是以下之一:数值型日期时间型类别型类别哈希型文本型。如果你愿意,也可以手动配置某一列为可用的类型之一。

    • 使用填充:如果数据集中有缺失值,该选项将根据所选方法进行就地填充。你可以选择的选项有自动(默认选项)、最常见值填充常数。特别是对于数值型特征,你还可以使用均值中位数填充策略。

      重要提示

      假设你有一个产品 ID 特征,明确说明每个客户注册的订阅产品。该特征将具有诸如 1,055 和 1,060 之类的数值。即使该特征实际上是类别型的,它可能会被错误地标记为数值型特征。如果训练数据集中缺少某些值,自动方法可能会用平均产品 ID 填充缺失值,这显然没有意义。AutoML 足够智能,能够理解如果一个数值型特征只有几个唯一值重复出现,则该特征可能是类别型的,但你可以通过将其标记为类别型来明确协助机器学习模型进行特征类型配置。

  9. 在这个向导页面上,你应该排除id特征。id特征提供了有关实际客户的信息,但它与分类问题无关,因此应该排除,以节省计算资源。点击保存,返回到你在步骤 4中看到的选择任务类型页面。

通过点击完成,如图 5.11所示,你可以完成 AutoML 实验的配置,运行将自动开始。浏览器将重定向到 AutoML 运行执行页面,你可以在该页面监控 AutoML 训练过程并查看训练结果。在下一节中,你将探讨该页面。

监控实验执行

在前一节中,配置自动化 ML 实验,你提交了一个 AutoML 实验以在远程计算集群上执行。一旦你提交了作业,浏览器应该会将你重定向到一个类似于以下的页面:

图 5.15 – 自运行完成以来第一次运行新的自动化 ML 实验

图 5.15 – 自运行完成以来第一次运行新的自动化 ML 实验

在页面顶部,实验运行的名称是自动生成的。在前面的截图中,名称是AutoML_05558d1d-c8ab-48a5-b652-4d47dc102d29。点击铅笔图标,你可以编辑此名称并将其更改为更易记的名称。将名称更改为my-first-experiment-run。在运行名称下方,你可以点击以下命令之一:

  • 刷新:这将刷新页面上提供的信息。在运行实验时,你可以获得最新的、最准确的信息。

  • 生成笔记本:这将创建一个包含所有所需 Python 代码的笔记本,用于使用 Azure ML SDK 运行相同的实验。你将在第八章《使用 Python 代码实验》中了解更多关于运行 AutoML 实验所需代码的内容。

  • 取消:这将取消当前的运行。仅当实验仍在运行时,此选项才可用。

    重要提示

    当你取消运行时,可能需要一段时间才能完成取消操作。你可以点击刷新按钮,查看取消过程的进度。

  • 删除:这将删除所选的运行记录。仅在运行已取消或已完成执行时才可启用。

运行实验页面提供了关于整个过程的大量信息,并通过标签进行结构化。默认情况下,你将从名为详细信息的标签开始。在此标签中,你将找到以下重要信息:

  • 在前面截图左侧的属性框中,最重要的信息位于以下字段:

    a) 状态,描述当前运行的状态。可以是正在运行、已取消、出错或已完成。

    b) 计算目标是运行所在的计算位置。

    c) 原始 JSON 是一个链接,允许你以机器可读格式查看当前运行的所有配置信息。

  • 在右侧的运行摘要框中,您将找到任务类型,即您正在训练的模型类型。点击查看配置设置,您可以查看当前实验的配置参数摘要。

  • 描述框允许您记录当前实验中正在评估的假设。点击铅笔图标,您可以添加实验运行的描述信息,这些信息将帮助您回忆在此实验中要寻找的内容以及结果。

运行页面的第二个选项卡名为数据防护。此选项卡提供关于您在实验中使用的数据集的详细定性和定量信息。根据任务类型,您将执行不同类型的验证。如果一切正常,则每个验证的状态为已通过;如果数据集存在需要解决的问题,则为已失败;如果 AutoML 发现数据集问题并已为您修复,则为已完成。在已完成的情况下,您可以通过点击+查看详细信息按钮查看 AutoML 修复数据集时的附加信息。

第三个选项卡称为模型,其中包含 AutoML 迄今为止训练的所有模型列表,如图 5.16所示。具有最佳指标分数的模型将列在顶部。表格显示算法名称、特定模型的解释结果(如果有)(已解释)、模型的分数(此处为准确率)、用于训练模型的数据百分比(采样)、以及模型训练的时间和持续时间信息(创建持续时间列)。如果您从列表中选择一个模型,将启用以下三个命令:

  • 部署启动选定模型的部署,您将在下一节了解有关部署的内容。

  • model.pkl,其中包含实际训练的模型和执行推理所需的所有支持文件。

  • 解释模型启动解释向导,在该向导中,您需要选择一个计算集群来计算特定模型的解释。默认情况下,AutoML 将解释最佳模型,但您可能希望解释额外的模型以进行比较。一旦计算出解释,您可以通过点击查看解释已解释列中查看它们。这将打开所选模型的解释选项卡,其中会显示报告。您将通过第十章《理解模型结果》进一步了解模型可解释性。

主页面上的第四个标签页,称为输出 + 日志,以简单的文件浏览器显示特定运行的输出和日志。这些日志是整个 AutoML 过程的日志。如果你想查看特定模型训练过程的日志,你需要从模型标签页中选择该模型,然后访问该子运行的输出 + 日志部分。该标签页中的文件浏览器允许你浏览左侧的文件夹结构。如果选择了一个文件,其内容将在右侧显示。

到目前为止,你已经成功训练了一些模型,并查看了最佳模型来预测客户是否会流失。在下一节中,你将学习如何仅通过几个点击操作将此模型投入使用。

将最佳模型作为 Web 服务进行部署

在上一节中,你浏览了运行实验页面,回顾了与运行执行相关的信息以及探索结果,即经过训练的模型。在本节中,我们将重新访问模型标签页,并开始将最佳模型作为 Web 服务进行部署,以便进行实时推理。导航到运行的详情页面,如图 5.15所示。让我们开始吧:

  1. 点击模型标签页。你应该会看到类似于这里显示的页面:图 5.16 – 模型标签页作为部署模型的起点

    图 5.16 – 模型标签页作为部署模型的起点

  2. 在此列表中,你可以选择任何你想要部署的模型。选择包含最佳模型的行,如前面的截图所示。点击列表顶部的部署命令。将出现部署模型对话框,如此处所示:图 5.17 – 部署模型对话框

    图 5.17 – 部署模型对话框

  3. myfirstmlwebservice中。

  4. 计算类型:你可以选择两种类型:

    • Azure Kubernetes 集群AKS):当你想为生产工作负载部署模型并且处理多个并行请求时,应该选择此选项。该选项支持基于密钥和基于令牌的身份验证,如果你想保护端点,可以使用它。如果你希望更快地进行模型推理,它还支持使用现场可编程门阵列FPGAs)。在这种情况下,你还需要指定要部署模型的 AKS 集群的计算名称属性。该列表应包含你在第四章 配置工作区中可能注册的所有推理集群。

    • Azure 容器实例:如果你计划进行功能测试,或者想在开发环境中部署模型,你可以将 Web 服务作为单一的 Azure 容器实例进行部署。这种计算类型较为便宜,但不支持扩展,并且只支持基于密钥的认证。对于本书内容,你可以选择这种类型来部署模型。

  5. 通过点击部署,你可以开始部署模型。

    在浏览器的右上角,将会出现一个弹出窗口,如下图所示,告知你模型已开始部署:

    图 5.18 – 端点部署窗口 – 部署进行中

    图 5.18 – 端点部署窗口 – 部署进行中

  6. 弹出窗口会迅速消失,但你可以通过点击右上角的通知铃铛图标重新查看,如下图所示:图 5.19 – Azure 机器学习工作室右上角的任务栏

    图 5.19 – Azure 机器学习工作室右上角的任务栏

  7. 模型部署需要几分钟时间。你可以查看通知来检查部署进度。如果通知变为绿色,如下图所示,则表示部署已完成:图 5.20 – 端点部署窗口 – 部署完成

    图 5.20 – 端点部署窗口 – 部署完成

  8. 通过点击通知中的部署详情链接,浏览器将会把你重定向到已部署模型的端点页面,如下图所示:图 5.21 – 已部署模型的端点页面

    图 5.21 – 已部署模型的端点页面

    重要提示

    有多种方法可以访问模型的端点页面。例如,你可以通过进入 Azure ML Studio 中的 资产 | 端点 菜单来查看所有已发布的端点列表。要到达相同的页面,请选择你要检查的端点。

    已部署模型的端点页面与实验运行页面类似,采用基于标签的结构。第一个标签叫做 详情,提供有关模型部署的信息。其中,最重要的信息位于前面截图中的 属性 区域,具体如下:

    • 服务 ID 是你在部署向导的 步骤 3 中指定的服务名称。

    • 部署状态 显示已部署或待部署模型的状态。端点可以处于五种状态。你可以在本章的 进一步阅读 部分找到更多关于状态及潜在问题的信息。

    • REST 端点是你可以复制到应用程序代码中的链接,用来通过 REST API 调用已部署的模型。

  9. 第二个标签页叫做测试,允许你测试已部署的模型。默认情况下,你会看到字段模式,这是一个表单,包含模型期望的所有输入,如下所示:图 5.22 – 已部署模型的端点页面

    图 5.22 – 已部署模型的端点页面

  10. 如果你想执行小批量推理,即一次发送多个记录,你可以从右上角切换到CSV模式。在此模式下,你可以将 CSV 文件的内容复制到将出现的文本框中,然后点击测试按钮。

    在任意模式下,一旦你点击测试按钮,输入数据将被提交到 REST API,并且会返回结果。

  11. 端点页面的第三个标签页叫做swagger.json,它是自动生成的,位于端点中。这个文件描述了 REST API 的预期输入和输出,通常由 web 开发人员使用来提供有关他们生产的 REST 端点的文档。

  12. 最后,部署日志标签页展示了模型部署的详细日志。你可以使用这个标签页来排查潜在的部署问题。

恭喜你 – 你已经成功部署了自己的实时端点,用于推断客户是否会流失!在下一节中,你将了解模型部署时创建的工件。

理解模型的部署

在上一节中,你将模型作为 REST 端点进行部署。在这一节中,你将了解幕后发生了什么,并发现部署过程中生成的工件。

你从 AutoML 训练出的模型列表开始。在这个列表中,你选择了一个模型并点击了部署命令。通过这样做,你将选定的模型注册到了 Azure ML 工作区,并且一旦完成,过程就继续进行,部署端点,正如下图所示:

图 5.23 – 从 AutoML 模型列表到端点部署

图 5.23 – 从 AutoML 模型列表到端点部署

模型注册在 Azure ML 工作区内创建了一个版本化记录,允许你跟踪用于训练特定模型的数据集以及该模型部署的位置。你将在第十二章,“用代码实现模型运作”中了解更多有关模型注册的信息。让我们来看看:

  1. 要查看这个模型注册,在 Azure ML Studio 中,导航至资产 | 模型。你将进入模型列表页面,如下所示:图 5.24 – 模型列表页面

    图 5.24 – 模型列表页面

    模型列表页面列出了 Azure ML 工作区中所有注册的模型。这些是由工作区跟踪的模型。每个模型都有一个唯一名称。您可以拥有同一模型的多个版本,当您尝试注册具有相同名称的模型时,这将自动发生。模型列表允许您选择一个模型并对其执行各种操作,如删除和部署它。

    重要提示

    只有当注册的模型没有被任何端点使用时,您才能删除它。

  2. 点击模型的名称属性后,您将进入所选注册模型的详细信息页面,如下所示:图 5.25 – 注册模型详细信息页面

    图 5.25 – 注册模型详细信息页面

    在这里,您可以获取有关模型的一般信息,比如是哪个运行训练了特定模型,使用了什么框架,以及该运行注册的实验名称。请注意,由于该模型是使用 AutoML 训练的,因此其框架是通用的 AutoML 框架。在第十二章,《通过代码实现模型运营》中,您将能够注册自己的模型,并指定您用来训练模型的框架。

    工件标签中,您将找到model.pkl文件,其中包含训练好的模型。在解释公平性标签中,如果已经为特定模型生成了解释性结果,您可以查看这些结果。您将在第十章,《理解模型结果》中深入了解模型解释性。在数据集标签中,您可以看到用于配置 AutoML 实验时使用的特定版本数据集的引用。这使得您可以在训练数据集与已部署的模型之间建立传承关系。

  3. 一旦模型被注册,部署向导将创建一个端点。返回到 Azure ML Studio,点击资产 | 端点菜单项。这将带您进入如下所示的端点页面:图 5.26 – 端点页面

    图 5.26 – 端点页面

    该列表显示了您从此 Azure ML 工作区部署的所有实时端点。您会注意到myfirstmlwebservice端点,这是您在上一节中部署的。点击其名称,您将进入端点页面,这个页面您在图 5.21中已经看过。

  4. 在幕后,这个端点是一个部署在packt-azureml-rg中的容器实例,紧邻您的 Azure ML 工作区资源。导航至 Azure 门户并打开packt-azureml-rg。您应该能看到与这里展示的资源类似的内容:图 5.27 – Azure 门户中 packt-azureml-rg 资源组的资源

    图 5.27 – Azure 门户中 packt-azureml-rg 资源组的资源

  5. 在这里,你将看到一个名为myfirstmllwebservice-容器实例已被部署,这是你在图 5.26中看到的端点的名称。这是托管你在上一节中部署的 REST API 的引擎。

    重要说明

    切勿直接从资源组删除 Azure ML 工作区的工件。这将导致工作区中出现孤立的注册项,如指向已删除容器实例的端点。

在本节中,你了解了从 AutoML 部署模型时发生的幕后过程。在下一节中,你将删除已部署的端点,以避免为不需要的实时端点支付费用。

清理模型部署

在本节中,你将清理已部署的模型。你应该删除那些不打算使用的模型部署。否则,你将为未使用的已配置资源付费。

导航到 Azure ML Studio。点击myfirstmlwebservice端点并点击删除命令。在弹出的窗口中点击删除以确认你要删除该端点:

图 5.28 – 删除实时端点弹窗

图 5.28 – 删除实时端点弹窗

在确认后,你在 Azure 门户中看到的端点和容器实例将被删除。如果你愿意,可以通过访问packt-azureml-rg 资源组来验证此操作。

总结

在本章中,你学习了如何配置 AutoML 过程,以发现能够预测客户是否会流失的最佳模型。首先,你使用 Azure 机器学习工作室的 AutoML 向导来配置实验。然后,你在工作室界面的实验部分监控运行的执行。一旦训练完成,你查看了训练好的模型,并查看了存储的关于最佳模型的信息。接着,你在 Azure 容器实例中部署了该机器学习模型,并测试了实时端点是否能够执行所请求的推断。最后,你删除了部署,以避免在 Azure 订阅中产生费用。

在下一章中,你将继续探索 Azure 机器学习工作室体验中的无代码/低代码部分,通过查看设计器,设计器允许你图形化地设计训练管道并实现生成的模型。

问题

你需要训练一个分类模型,但在 AutoML 过程中只考虑线性模型。以下哪项可以让你在 Azure 机器学习工作室体验中实现这一点?

a) 将所有非线性算法添加到阻止算法列表中。

b) 将退出标准选项设置为度量得分阈值。

c) 禁用自动特征化选项。

d) 在分类任务中禁用深度学习选项。

进一步阅读

本节提供了作为有用的网络资源的额外内容:

第六章:第六章:可视化模型训练与发布

Azure 机器学习AzureML)Studio 提供了一个设计器体验,帮助你在开发模型时通过拖放和配置训练与推理管道。在本章中,你将概览设计器。随后,你将创建一个训练过程。在了解设计器使用的整体流程后,本章将通过创建一个推理管道并将训练好的模型工件发布为服务端点来结束。

在本章中,我们将覆盖以下主题:

  • 设计器概述

  • 设计训练过程

  • 创建批量和实时推理管道

  • 部署实时推理管道

技术要求

你需要拥有 Azure 订阅。在该订阅中,你需要一个packt-azureml-rg。此外,你需要有ContributorOwner角色的packt-learning-mlw,具体如在第二章中所述,部署 Azure 机器学习工作区资源

你还需要在你的工作区中注册churn-dataset,该工作区是在第五章中创建的,让机器来进行模型训练

设计器概述

AzureML Studio 提供了一个图形化设计器,可以让你以可视化方式创建管道。根据定义,管道是一个可以独立执行的子任务流,描述了一个机器学习任务。在设计器中,你可以创建三种类型的管道:

  • 训练管道:这些管道用于训练模型。

  • 批量推理管道:这些管道用于将预训练模型用于批量预测。

  • 实时推理管道:这些管道用于暴露一个 REST API,允许第三方应用程序使用预训练模型进行实时预测。

要创建批量和实时管道,你需要先编写一个训练管道。在接下来的部分中,你将学习如何创建训练管道,然后在此基础上生成批量和实时管道。在第十一章中,与管道协作,你将学习如何通过代码编写类似的管道。

要开始编写管道,你需要访问设计器主页。点击设计器菜单项,导航到主页,如下图所示:

图 6.1 – 设计器主页

图 6.1 – 设计器主页

新建管道 + 按钮旁边,你将看到几个其他按钮,带有不同的现成示例管道。稍后请熟悉这些示例。为了展示设计器的最新功能,这些示例会定期更新,且它们是一个很好的入门资源。

在本章中,我们将从零开始创建一个新的管道。点击+按钮将带你进入创作视图/屏幕,我们将在下一节中探索这个视图。

创作视图

使用设计器构建管道的主页面如下所示:

图 6.2 – AzureML 设计器创作视图

图 6.2 – AzureML 设计器创作视图

我们将在这里描述主页面的用户界面,前面的截图作为参考:

  • 通过点击左上角的汉堡菜单图标 (),你可以隐藏或显示前面截图中标记为1的 AzureML 主菜单。从现在起,我们假设该区域已被隐藏。

  • 在标记为2的区域,你可以找到所有可以拖放到画布上的资产,这些资产在前面的截图中被标记为3。通过将不同的资产拖放到画布上,你可以构建一个管道。你将在本章的了解资产库部分深入了解该区域。

  • 在右侧标记为4的区域,你将找到设置。这个区域也被称为详情页。此视图会根据你在画布中选择的内容而变化。如果你在画布区域中没有选择任何资产,你将看到你正在构建的管道的设置,并且可以选择一个默认计算目标来执行每个管道步骤。如果你选择了一个资产,你将找到该资产的各种配置选项。

  • 区域test-pipeline

  • 在区域5,你还会找到设置按钮 ()。通过该按钮,你可以隐藏/显示前面截图中标记为4设置区域。在同一区域,你还可以找到其他图标,用于保存或删除管道,以及在画布上进行撤销、重做和搜索操作。选择工具 () 是画布上的标准光标。稍后,在我们构建管道时,我们将切换到手型工具 () 来移动画布上选中的部分。点击设置以隐藏区域4,并扩大画布区域。

  • 最后一个区域,在前面截图中标记为6,提供了提交、发布和克隆管道的功能,我们将在创建批处理和实时推理管道部分中讨论。

在继续下一节之前,你需要配置管道用于执行所有步骤的默认计算目标属性。打开管道设置,并选择你在第五章中使用的计算集群,让机器进行模型训练

在下一部分,你将探索标记为2的区域,也被称为资产库

了解资产库

要构建管道,你需要将不同的资产拼接在一起。在本节中,你将查看设计器的资产库中可用的不同资产。在图 6.2中,我们有 96 个可用的资产。这个数字取决于你在 AzureML 工作区中注册了多少数据集,并且在 AzureML 的未来版本中,你甚至可能能够创建自己的编码资产。下图显示了资产库中可用的类别以及它们包含的资产类型(也称为模块)的简要说明:

图 6.3 – AzureML 设计器资产库中的类别

图 6.3 – AzureML 设计器资产库中的类别

这个库中有三种类型的资产:

  • 数据集和手动输入的模块

  • 未训练的模型

  • 执行某些数据操作的模块

在你构建第一个端到端机器学习训练管道时,你将从这个资产库中拖放组件。在接下来的章节中,你将看到每个资产的外观以及如何在它们之间连接不同的资产。

探索资产的输入和输出

我们从资产库中拖放的每个资产都是我们正在构建的管道中的一个模块。一个模块看起来类似于以下截图中显示的示例模块:

图 6.4 – 一个具有两个输入和一个输出的示例模块

图 6.4 – 一个具有两个输入和一个输出的示例模块

让我们从上到下描述这个模块:

  • 顶部有零个、一个或多个输入端口:在前面的截图中,示例模块接受两个输入。你可以将另一个模块的输出连接到下一个模块的输入。

  • 在模块的中间,模块名称描述了该模块的功能。我们的示例是一个训练模型模块,它会使用右侧输入端口给定的数据训练一个从左侧输入端口传入的未训练模型。

  • 如果你在画布中选择模块,模块的详情页面将出现在图 6.2中标记为4的区域。这一页面对于每个模块都是不同的。你可以配置各种选项,如短描述或将执行该特定模块的计算目标。

  • 在模块名称下方,你可以看到该模块的描述文本。你可以通过选择模块并编辑模块详情页面上的文本来修改该描述。在我们的示例中,模块描述显示的是示例模块的文本。

  • 在模块的底部,有一个或多个输出端口,你可以将它们拖动并连接到下一个模块。

在本节中,你已经探索了 AzureML Studio 设计器的各个方面。在下一节中,你将开始编写你的第一个训练管道。

使用设计器构建管道

在本节中,我们将创建一个训练管道,用于训练在上一章中使用的客户流失数据集的机器学习模型。

当你开始设计训练流程时,我们建议采用如下图所示的7 步机器学习方法,它包含了创建机器学习模型所需的所有步骤:

图 6.5 – 7 步机器学习

图 6.5 – 7 步机器学习

这 7 步的旅程是现实场景中的宝贵清单,可以确保你不会遗漏任何步骤。在这个过程中,你将需要各种组件、转换和模型,这些都可以在资产库中找到。为了简化流程,我们将跳过一些你设计的流程中的步骤。在这一节中,你将从准备数据集开始,准备好训练模型。然后,你将评估模型并存储它。在下一节中,你将使用该模型创建批处理和实时流水线,利用模型进行预测。

让我们从获取将用于训练模型的数据开始,这将在下一节中进行。

获取数据

第一步是选择你将用于训练模型的数据集:

  1. 在资产库中,点击数据集类别旁的箭头展开。你应该可以看到你在第五章中创建的流失数据集让机器进行模型训练图 6.6 – 数据集类别下的流失数据集

    图 6.6 – 数据集类别下的流失数据集

  2. 流失数据集拖动到画布上:图 6.7 – 带有流失数据集的画布

    图 6.7 – 带有流失数据集的画布

    到此,你已经完成了数据收集步骤,意味着你可以进入7 步机器学习的第二步。

  3. 下一步是数据准备。通过拖动选择数据集中的列模块,将其添加到流程中,该模块可以在资产库中的数据转换类别下找到。

  4. 现在,你需要在数据集和模块之间创建流程。你可以通过从数据集的输出端口(数据集底部的小圆圈)拖动到选择数据集中的列模块的输入端口(模块顶部的小圆圈)来完成,如下图所示:图 6.8 – 在数据集和处理模块之间创建流程

    图 6.8 – 在数据集和处理模块之间创建流程

  5. 下一步是配置选择数据集中的列模块。选择画布上的模块后,点击画布右侧详细信息窗格中的编辑列链接,如上图所示。选择列对话框将会出现。参见以下截图,了解该弹出窗口的最终配置。

  6. 在该弹出窗口中,从下拉菜单中选择所有列

  7. 点击+按钮添加第二行。

  8. 从下拉菜单中选择排除

  9. 从第二个下拉框中选择列名称

  10. 从最后一个下拉框中选择id列。

    对话框页面应该如下所示:

    ![图 6.9 – 选择列对话框]

    ](https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/az-ds-ass-cert-gd/img/B16777_06_009.jpg)

    图 6.9 – 选择列对话框

  11. 点击保存以关闭弹出窗口。

到目前为止,你已经选择了将用于训练模型的数据集,并通过移除id列(在训练过程中不需要此列)准备了数据。在下一节中,你将通过添加未训练的模型、训练模型的模块以及用于评分和评估训练模型的模块来完善你的训练流程。

准备数据并训练模型

现在,你将选择你将要训练的模型。在第五章中,让机器进行模型训练,你确定了投票集成是给定数据的最佳表现模型。这种类型的模型是不同模型的组合,包括随机森林。为了简化示例,你将使用一个类似于随机森林两类决策森林模型。我们开始吧:

  1. 在资产库中导航到机器学习算法类别。你会注意到几个子类别,其中包括分类。从该子类别中,拖动并将两类决策森林模块拖放到画布上。

  2. 对于模型训练,你将需要两个额外的模块:拆分数据模块,可以在资产库的数据转换类别中找到,以及训练模型模块,可以在模型训练类别中找到。将这两个模块拖放到画布上。

  3. 你需要扩展你在上一节中创建的数据流,将数据传递通过新的模块。从数据集中的选择列模块拉取一个输出端口拆分数据模块的输入端口

  4. 你需要在模块的详细信息面板中配置拆分数据模块,如下图所示。将第一个输出数据集中的行比例设置为0.7。这样,70%的数据将通过左输出端口区域传送,用于训练模型,30%的数据将通过右输出端口区域传送,用于测试。

  5. 训练模型模块接受两个输入。在左输入端口区域,你需要传递一个未训练的模型,该模型将使用右输入端口区域提供的数据进行训练。从两类决策森林模块拉取一个输出端口训练模型模块的左输入端口区域。

  6. 拆分数据模块的左输出端口区域拖动到训练模型模块的右输入端口区域。你的画布应该如下所示:![图 6.10 – 训练模型模块缺少一些配置]

    ](https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/az-ds-ass-cert-gd/img/B16777_06_010.jpg)

    图 6.10 – 训练模型模块缺少一些配置

  7. 在前面的截图中,训练模型模块中有一个橙色的感叹号。这个标记表示该模块的某些配置错误。到目前为止,你已经配置了训练模型和使用哪些数据进行训练,但你还没有定义模型要预测哪一列。这个列被称为标签列。要配置标签列,选择画布中的模块,然后点击编辑列链接。这将打开如下截图所示的标签列对话框。从下拉列表中选择churned列,然后点击保存图 6.11 – 选择模型将要预测的列

    图 6.11 – 选择模型将要预测的列

    到目前为止,训练管道已完成了机器学习的 7 个步骤中的前四个步骤。接下来的步骤是评估模型。

  8. 评分模型模块拖放到画布上,该模块可以在资产库中的模型评分与评估类别下找到。该模块接受训练好的模型作为左输入端口区域的数据,以及作为右输入端口区域的数据集。该模块的输出是一个包含模型对输入数据集进行推理结果的数据集。

  9. 分割数据模块的右输出端口区域连接到评分模型模块的右输入端口区域。这将创建一个数据流,将原始数据的 30%部分传递到评分模型模块。

  10. 输出端口区域连接到训练模型模块的左输入端口区域。评分模型模块将使用训练好的模型对输入数据进行推理。

  11. 评估模型模块拖放到画布上,该模块可以在资产库中的模型评分与评估类别下找到。该模块将比较模型所做的预测与churned列中存储的值。

  12. 评分模型模块的输出端口区域连接到评估模型模块的左输入端口区域。

    如果你已经按照步骤操作,画布应该如下所示:

    图 6.12 – 完整的训练管道

图 6.12 – 完整的训练管道

到目前为止,你已经编写了一个训练管道,完成了以下操作:

  • 从数据集中移除id列。

  • 将数据分为训练数据集和验证数据集。训练数据集包含原始数据的 70%。验证数据集包含剩余的 30%。

  • 使用训练数据集训练二类决策森林

  • 使用训练好的模型对验证数据集进行评分。

  • 通过检查评分数据集中的结果来评估模型的性能。您将能够在评估模型模块中查看训练模型的度量。

在下一节中,您将执行此管道来训练模型。

执行训练管道

在上一节中,您创建了一个完整的训练管道,接下来您将通过创建一个新的管道运行来执行它。让我们开始吧:

  1. 点击右上角的提交按钮,设置管道运行对话框将打开,如下图所示。

  2. 您需要创建一个新的实验并命名为test-pipeline。选择创建新实验单选按钮,然后输入该名称。

  3. 请注意,管道将在您在作者界面/视图部分中选择的默认计算目标上执行。点击提交按钮开始执行训练管道:

图 6.13 – 准备执行训练管道

图 6.13 – 准备执行训练管道

一旦管道执行完成,设计器将类似于以下界面:

图 6.14 – 成功运行管道

图 6.14 – 成功运行管道

至此,您已成功完成了第一个管道的开发和训练。当管道执行完成后,创建推理管道按钮将出现。以下部分将描述在创建推理管道时可选的不同选项。

创建批量和实时推理管道

本节将讨论从设计器部署推理管道的两种选项:批量实时

  • 使用批量预测,您可以异步地对大型数据集进行评分。

  • 使用实时预测,您可以实时地对一个小数据集或一行数据进行评分。

当您创建一个推理管道时,无论是批量的还是实时的,AzureML 会处理以下事项:

  • AzureML 将训练好的模型和所有训练数据处理模块作为资产,存储在数据集类别下的资产库中。

  • 它会自动删除不必要的模块,如训练模型拆分数据

  • 它将训练好的模型添加到管道中。

特别是对于实时推理管道,AzureML 将在最终管道中添加Web 服务输入Web 服务输出

让我们从创建一个批量管道开始,这将是您在下一节中要做的事情。

创建批量管道

在本节中,您将创建一个批量推理管道。让我们开始吧:

  1. 点击创建推理管道下拉菜单,位于提交按钮旁边,并选择批量推理管道。此操作将创建批量推理管道标签页,如下图所示:图 6.15 – 显示默认生成管道的批量推理管道标签页

    图 6.15 – 显示默认生成管道的批量推理管道选项卡

  2. 通过添加管道参数,你将能够在运行时更改管道的行为。在我们的案例中,我们希望参数化用于预测的数据集。要参数化输入数据集,点击churn-dataset,然后在右侧详细信息窗格中勾选设置为管道参数复选框。

  3. 参数名称文本框中的默认参数名称更改为batchfile

  4. 点击发布按钮,弹出设置已发布管道对话框,如以下截图所示。

  5. 选择创建新单选按钮,以定义新的管道端点。此端点用于触发即将发布的管道。

  6. 保持新管道端点名称字段的默认值不变。它应该显示为test-pipeline-batch inference

  7. 你可以通过填写管道端点描述(可选)字段,向已发布的端点添加描述。在该字段中写入批量管道参数名称 batchfile 的测试

  8. 保持所有其他设置不变。完成后的对话框页面应该如下所示:![图 6.16 – 已发布管道对话框页面

    图 6.16 – 已发布管道对话框页面

  9. 点击发布按钮。

    一旦管道的端点成功发布,设计器中将显示如下截图中的消息。test-pipeline-batch inference链接将引导你到已发布的管道:

图 6.17 – 发布成功

现在你已经发布了一个批量推理管道,你可以通过 AzureML Studio 界面触发它。在第十一章与管道一起工作将管道发布为端点部分,你将学习更多关于这些管道以及如何将它们与第三方应用程序集成的内容。

在下一节中,我们将基于训练管道创建实时管道。

创建实时管道

在本节中,你将创建一个实时推理管道。让我们开始吧:

  1. 在设计器中选择训练管道选项卡,该选项卡位于图 6.15的左上角。

  2. 点击提交按钮旁边的创建推理管道下拉菜单,并选择实时推理管道。这将生成默认的实时推理管道,如以下截图所示:![图 6.18 – 默认实时推理管道

    图 6.18 – 默认实时推理管道

    在我们部署此管道之前,需要进行一些更改。

  3. 点击选择数据集中的列模块,并点击右侧详细信息窗格中的编辑列链接。

  4. 点击加号(+)图标,在选择列对话框中添加新行。

  5. 从相应的下拉菜单中选择排除列名,并输入churned作为要排除的列名。对话框页面应如下所示:图 6.19 – 从传入数据集中排除 id 和 churned 列

    图 6.19 – 从传入数据集中排除 id 和 churned 列

  6. 从资产库中的数据转换类别中,将应用 SQL 转换模块拖到画布上。将其放置在Web 服务输出模块的上方。

  7. 评分模型模块的输出端口区域连接到应用 SQL 转换模块的左输入端口区域。

  8. 删除评分模型模块与Web 服务输出模块之间的连接。为此,点击连接两者模块之间的连接线。选中后,点击垃圾桶图标或按键盘上的删除按钮。连接器应被移除。

  9. 删除画布中的评估模型模块。

  10. 应用 SQL 转换模块的输出端口区域连接到Web 服务输出模块的输入端口区域。

  11. 选择应用 SQL 转换模块。

  12. 点击应用 SQL 转换详细面板中的编辑代码链接,并用以下查询替换默认查询:

    select [Scored Labels] from t1
    

    此 SQL 转换仅选择预测值,该值存储在评分标签列中。

  13. 保存按钮。修改后的管道应如下图所示。

  14. 为了确保您设计的管道正确执行,您需要使用提交按钮运行一次。将弹出设置已发布的管道对话框。

  15. 您需要在实验中执行管道。选择创建新单选按钮。

  16. 使用test-pipeline-real-time-inference作为新实验名称

  17. 保持其他字段的默认值不变,点击提交

    您的管道应该可以执行,且画布应如下所示:

图 6.20 – 修改后的实时推断管道

图 6.20 – 修改后的实时推断管道

在验证管道可以正常执行后,您可以将其部署为实时端点。关于将托管实时端点的基础设施,您有两种选择。您可以选择将其部署到Azure 容器实例ACI)或Azure Kubernetes 服务AKS)集群中。ACI基础设施适用于测试目的,而AKS基础设施则支持更好的生产环境。在我们的案例中,我们将部署到ACI,您将在下一部分了解有关内容。

部署实时推断管道

在本节中,您将部署在实时推断管道设计器标签中创建的示例实时推断管道。让我们开始吧:

  1. 点击部署按钮。这将弹出设置实时端点的弹窗,如下图所示。

  2. 设置实时端点弹窗中,选择部署新实时端点单选按钮选项。

  3. 名称文本框中,输入first-real-time-endpoint

  4. 描述文本框中,输入第一个实时管道的容器部署

  5. 点击计算类型下拉列表,选择Azure 容器实例

  6. 你无需修改高级设置。完成的弹窗应如下所示:图 6.21 – 设置实时端点弹窗

    图 6.21 – 设置实时端点弹窗

  7. 点击部署按钮以配置你的实时端点。这将需要几分钟时间。

成功部署管道后,你将在 AzureML Studio 的资产 | 端点中找到新部署的管道。你刚部署的端点与在第五章中部署的端点相同,让机器进行模型训练。你可以通过网页界面进行测试。你将在第十二章中深入了解如何使用类似的端点,通过代码使模型操作化。在继续之前,你应当删除实时端点,以免产生费用。请参照第五章中的清理模型部署部分,删除你刚刚部署的端点。

总结

本章介绍了管道设计器,它允许我们通过拖放方式创建 AzureML 管道。你基于客户流失数据集和二分类决策森林模型构建了你的第一个训练管道。我们讨论了三种管道类型,编写了训练管道,创建了批量管道,并开发和部署了实时管道。

本章总结了 AzureML 提供的无代码、低代码功能。在下一章,你将开始使用 AzureML Python SDK。AzureML Python SDK 允许你通过代码训练模型并创建机器学习管道,这对于 DP-100 考试至关重要。

问题

部署实时管道有哪些选项?

  • Azure 容器实例仅适用

  • Azure 容器实例Azure Kubernetes 服务

  • Azure 容器实例Azure 虚拟机

  • Azure 虚拟机仅适用

进一步阅读

本节提供了一些有用的网络资源,帮助你扩展 AzureML 设计器的知识:

第三部分:高级数据科学工具和功能

在本节中,您将深入了解Azure 机器学习AzureML)Python SDK。该 SDK 允许您使用 Python 代码配置工作区并协调端到端的数据科学流程。在这里,您将更深入地了解 AzureML 平台的运作方式,这对于通过 DP-100 考试至关重要。

本节包含以下章节:

  • 第七章**,AzureML Python SDK

  • 第八章**,使用 Python 代码进行实验

  • 第九章,优化机器学习模型

  • 第十章**,理解模型结果

  • 第十一章**,使用管道

  • 第十二章**,通过代码实现模型操作

第七章:第七章:AzureML Python SDK

本章中,你将了解 AzureML Python 软件开发工具包SDK)的结构,以及如何使用它,这对 DP-100 考试至关重要。你将学习如何使用内建于 AzureML Studio 网页门户中的笔记本功能,这是一个提高编码生产力的工具。使用笔记本编辑器,你将编写一些 Python 代码,更好地理解如何管理工作区中注册的计算目标、数据存储和数据集。最后,你将重新访问在 第二章中讨论过的 Azure CLI, 部署 Azure 机器学习工作区资源,通过 AzureML 扩展来执行工作区管理操作。这将允许你编写脚本并自动化工作区管理活动。

本章将涵盖以下主要主题:

  • Python SDK 概述

  • 使用 AzureML 笔记本

  • 使用 AzureML SDK 的基础编码

  • 使用 AzureML CLI 扩展

技术要求

你需要访问一个 Azure 订阅。在该订阅中,你需要一个packt-azureml-rg。你还需要拥有ContributorOwner权限的packt-learning-mlw,如 第二章中所述, 部署 Azure 机器学习工作区资源

你还需要具备基础的Python语言知识。本章中的代码片段适用于 Python 3.6 或更高版本。你应该了解 Jupyter 笔记本的基本工作原理,以及你在某个单元中定义的变量如何在其他单元的执行上下文中存在。

你可以在 GitHub 上找到本章的所有笔记本和代码片段,链接为bit.ly/dp100-ch07

Python SDK 概述

AzureML SDK是一个 Python 库,可以让你与 AzureML 服务进行交互。它还为你提供了数据科学模块,帮助你在机器学习过程中取得进展。AzureML SDK 通过一个 Python 与 R 的互操作包在 R 编程语言中也可用。

SDK 由多个包组成,这些包将不同类型的模块组织在一起,你可以将这些模块导入到代码中。所有 Microsoft 支持的模块都位于以azureml开头的包中,如azureml.coreazureml.train.hyperdrive。下图提供了 AzureML SDK 中最常用包的广泛概览,以及你将在本书和考试中看到的关键模块:

图 7.1 – AzureML SDK 模块和重要类

图 7.1 – AzureML SDK 模块和重要类

请注意,azureml.core包中所有的关键类也可以从相应的子模块导入。例如,Experiment类可以通过以下两种方式导入:

from azureml.core import Experiment
from azureml.core.experiment import Experiment

这两个代码片段将加载相同的类,您只需要使用其中一个。第一个从 azureml.core 软件包加载类,而第二个从 experiment 模块(一个名为 experiment.py 的文件)加载类,该模块是 azureml.core 软件包的一部分。如果您在阅读各种代码示例时注意到这种类型的差异,请不要感到惊讶。

重要提示

在考试中,您无需记住这些软件包,但您需要从下拉列表中选择合适的一个。例如,您可能会被要求完成一些引用 AutoMLConfig 的代码,而您可能需要在 azureml.automl 软件包和 azureml.pipeline 软件包之间进行选择,这个选择在阅读完接下来的几章后会变得更加明显。书中的所有代码示例都会在脚本的顶部导入所有所需的软件包,帮助您熟悉类的位置。

在本章中,您将重点学习 SDK 类,这些类允许您控制 AzureML 工作区,以及在工作区中部署的计算资源、数据存储区和您可以在工作区中注册的数据集。

在接下来的部分,您将学习如何利用 AzureML Studio 内置的 笔记本 体验来编写 Python 脚本。

在 AzureML 笔记本中工作

AzureML Studio 提供与多个代码编辑器的集成,允许您编辑笔记本和 Python 脚本。这些编辑器由您在 第四章 中配置的计算实例提供支持,配置工作区。如果您为了节省费用停止了该计算实例,请导航至 管理 | 计算 并启动它。从此视图,您可以打开所有与 AzureML Studio 集成的第三方代码编辑器,如下图所示:

图 7.2 – Azure Studio 集成的第三方代码编辑器列表

图 7.2 – Azure Studio 集成的第三方代码编辑器列表

最广为人知的开源数据科学编辑器是 Jupyter Notebook 及其更新版本 JupyterLab。您可以通过点击前面截图中显示的相应链接打开这些编辑环境。这将打开一个新的浏览器标签页,如下图所示:

图 7.3 – 计算实例提供的 JupyterLab 和 Jupyter 编辑体验

图 7.3 – 计算实例提供的 JupyterLab 和 Jupyter 编辑体验

除了这些第三方代码编辑体验外,AzureML Studio 还提供了一个内置的增强型笔记本编辑器,允许你在 Studio 界面内编辑、共享和协作,如下图所示。这个编辑器建立在 Jupyter Notebook 服务之上,但提供了更改进的代码编辑体验,比如内联错误高亮、自动代码补全、弹出窗口显示即将调用的方法的参数信息等其他功能,这些功能统称为IntelliSense

图 7.4 – 内置于 AzureML Studio 中的增强型笔记本体验

图 7.4 – 内置于 AzureML Studio 中的增强型笔记本体验

笔记本编辑器带有一个嵌入式示例库,其中包含最新的笔记本目录,展示了最新 AzureML SDK 几乎所有的功能。一旦你找到相关的笔记本,你可以查看其内容,如果你想修改它,可以将其克隆到你的工作区,这个操作会复制 Jupyter 笔记本及与该笔记本相关的脚本和数据,如下图所示:

图 7.5 – 帮助你快速掌握 AzureML SDK 功能的示例笔记本

图 7.5 – 帮助你快速掌握 AzureML SDK 功能的示例笔记本

重要提示

这些笔记本已更新为最新版本的 AzureML SDK。这些笔记本所在的代码库可以在 GitHub 上找到,网址为github.com/Azure/MachineLearningNotebooks/。你可以使用 GitHub 提交问题或通过 GitHub 的搜索功能查找代码片段。

每个 AzureML 工作区都配有一个存储帐户,正如在第二章中提到的,部署 Azure 机器学习工作区资源。此存储帐户包含一个以code-为前缀的文件共享,该共享托管工作区内所有可用的笔记本和脚本,如下图所示。你在 Studio 体验中看到的文件,就是存储在该文件共享位置中的文件,在Files选项卡中:

图 7.6 – Azure 门户视图,显示托管所有 AzureML 工作区代码文件的文件共享 AzureML 工作区中的代码文件

图 7.6 – Azure 门户视图,显示托管所有 AzureML 工作区代码文件的文件共享

每个用户在Users文件夹下都有一个单独的文件夹,用于组织他们的文件。所有具有特定 AzureML 工作区访问权限的用户都可以访问这些文件。这使得代码共享变得非常容易。你可以通过在浏览器中打开文件,将其指向具有 AzureML 工作区访问权限的某个人;然后,你可以分享浏览器导航栏中的 URL。

在本节中,您将创建一个笔记本,在其中编写和执行本章中的代码片段。要处理您的文件,请导航到chapter07,然后创建一个名为chapter07.ipynb的笔记本。

点击用户名旁边的三个点,如下截图所示。从那里,您可以创建文件夹结构并从本地计算机上传文件。点击创建新文件夹选项,如下截图所示:

图 7.7 – 在 AzureML Studio 的 Notebooks 体验区域中创建新文件夹选项

图 7.7 – 在 AzureML Studio 的 Notebooks 体验区域中创建新文件夹选项

填写弹出的对话框以创建名为chapter07的文件夹。选择该文件夹,然后点击三个点。然后,选择Users/<username>/chapter07,这意味着该文件将放置在新创建的文件夹中。关于chapter07.ipynb并点击Create按钮,如下截图所示:

图 7.8 – 创建一个笔记本以编写和执行本章的 Python 脚本

图 7.8 – 创建笔记本以编写和执行本章 Python 脚本

这将在您的文件夹中创建两个文件:笔记本文件,将在编辑器窗格中打开,以及一个.amlignore文件,您将在第八章使用 Python 代码进行实验中详细了解该文件:

图 7.9 – 在 AzureML Studio 中编辑笔记本

图 7.9 – 在 AzureML Studio 中编辑笔记本

从前述截图的左侧开始,Notebooks 体验提供以下内容:

  1. 文件资源管理器,您可以在其中创建或上传新文件,并删除、下载、重命名或移动您或您的同事在此工作区中创建的现有文件。

  2. 正在打开文件的名称。请注意,如果您在名称旁边看到一个星号 – 例如,*** chapter07.ipynb** – 这意味着该文件尚未保存。您可以使用 Windows 和 Linux 的Ctrl + S快捷键或 macOS 的Cmd + S快捷键保存该文件。或者,您可以从文件选项菜单中选择保存选项,您将在下面阅读到。

  3. 文件选项菜单,提供保存操作和焦点模式等选项,焦点模式会将编辑器面板扩展到浏览器标签的大部分空间。这是一个动态菜单,取决于你当前正在编辑的文件类型。在前面的截图中,打开的是一个笔记本,菜单提供了其他操作,如清除输出、重启 Python 内核或查看当前加载的 Python 内核中的变量。你还可以通过点击菜单图标(即四个垂直线的图标)并从编辑器选项中选择相应的编辑器来在 Jupyter 或 JupyterLab 中编辑同一文件。特别是对于 VS Code,一个非常流行的跨平台免费代码编辑器,主栏中提供了在 VS Code 中编辑的选项。

  4. 管理当前正在编辑特定文件的计算实例的能力。在此部分,你可以快速创建一个新的计算实例或启动/停止现有的实例。

  5. 选择执行笔记本的环境的能力。默认情况下,选择的是 AzureML Python 内核,这是已安装 AzureML SDK 的环境。如果你正在编辑 R 文件,可以将内核更改为 R 内核,或者如果你想自定义工作环境,也可以创建自己的内核。

  6. 主编辑器面板。这是你可以修改选定文件的地方。

    在你的情况下,编辑器面板将为空,且只会显示一个空单元格,如下图所示。每个单元格可以包含Markdown格式的文本或 Python 代码。你可以通过点击弹出菜单并选择M****↓图标来将单元格转换为代码单元:

    图 7.10 – 一个空的代码单元格

    图 7.10 – 一个空的代码单元格

  7. 点击M****↓图标,然后点击编辑图标,在单元格中添加以下 Markdown 文本:

    # Chapter 07 code snippets
    This notebook contains all code snippets from chapter 7.
    
  8. Shift + Enter键完成编辑,执行单元格,这将在本例中渲染格式化的文本,并将光标移到下一个单元格。默认情况下,下一个单元格将是代码单元。将以下 Python 代码添加到该单元格中:

    print('Hello world')
    

    请注意,当你开始输入时,会出现一个弹出窗口,其中包含代码建议,你可以使用箭头键选择。你可以通过按下键盘上的Enter键来确认选择。这个列表是智能的,它会显示与你输入的内容匹配的类名,并且还会显示一些常用类,可能是因为你拼写错误或者忘记输入某些字母。例如,以下截图显示了PermissionError类,因为你可能忘记输入print语句并且不完整,当代码中的部分存在语法错误时,会有波浪下划线标记。要执行代码单元,可以按Shift + Enter组合键,或者点击单元格左侧的圆形按钮:

图 7.11 – IntelliSense 提示适合当前脚本范围的方法和类

图 7.11 – IntelliSense 提示适合当前脚本范围的方法和类

如果在执行代码单元时发生错误,错误信息将显示在单元格的底部,Traceback 信息将出现在单元格的输出部分,如下图所示。你可以更新单元格的内容并重新运行单元格以修复此错误:

图 7.12 – 笔记本单元执行期间的脚本错误

图 7.12 – 笔记本单元执行期间的脚本错误

在本节中,你学习了如何使用内置的笔记本体验来编写 Python 脚本。在下一节中,你将开始编写利用 AzureML SDK 的代码片段。

使用 AzureML SDK 进行基础编码

你将要使用的第一个类是 AzureML 的 Workspace 类,这个类允许你访问工作区内的所有资源。要创建对工作区的引用,你需要以下信息:

  • ab05ab05-ab05-ab05-ab05-ab05ab05ab05。你可以在 Azure 门户中的 属性 标签下找到该订阅的 ID。

  • 资源组名称:包含 AzureML 工作区组件的资源组。

  • 工作区名称:AzureML 工作区的名称。

你可以通过运行以下赋值语句将这些信息存储在变量中:

subscription_id = '<Subscription Id>'
resource_group = 'packt-azureml-rg'
workspace_name = 'packt-learning-mlw'

创建工作区引用的第一种方法是实例化 Workspace 类,如以下代码片段所示。

from azureml.core import Workspace
ws = Workspace(subscription_id, resource_group, workspace_name)

这是你在 第四章 中看到的代码片段,配置工作区,当你创建数据集并探索该数据集的 消费 标签时。

重要说明

本书假设你将在上一节中创建的笔记本中编写代码,并通过执行 pip install azureml-sdk 命令使用 azureml-sdk 包编辑笔记本。在这种情况下,你将被提示使用交互式认证来验证设备,这一点你将在下一节中阅读到。

创建对 AzureML 工作区引用的另一种方法是使用 Workspace 类的 get() 方法,如以下代码片段所示:

from azureml.core import Workspace
ws = Workspace.get(name=workspace_name,
                   subscription_id=subscription_id,
                   resource_group=resource_group)

在这里,关于 ws 变量,你分配了一个引用,它指向与本节开始时在 workspace_namesubscription_idresource_group 变量中指定的 namesubscription_idresource_group 值相匹配的 AzureML 工作区。

重要说明

在 Python 中,你可以通过按名称或位置传递参数来调用函数。在之前的示例中,我们通过按名称传递参数来调用 Workspace.get()——也就是说,我们明确指定了对于 name 参数,我们传递的是 workspace_name 变量的值。使用这种方法时,参数的顺序并不重要。而在前一个示例中,我们通过按位置传递参数来实例化 Workspace 类。你没有使用 workspace_name=workspace_name 这种赋值方式。这意味着你是根据 Workspace 类构造函数声明参数的顺序来赋值的。本书以及考试中,你将看到这两种赋值方式。

前面提到的两种获取 AzureML 工作区引用的方式是相同的。然而,主要问题在于它们将工作区硬编码在了脚本中。假设你想和朋友分享一个笔记本,但你在笔记本中硬编码了订阅 ID、资源名称和工作区名称。你的朋友就必须手动去编辑那个单元格。这个问题在你想写一个能够在多个环境中运行的脚本时变得尤为明显,比如开发环境、质量保证环境和生产环境。

Workspace 类提供了 from_config() 方法来解决这个问题。该方法会搜索文件夹树结构中的 config.json 文件,文件格式如下,并包含本节开始时提到的所有信息:

{
  "subscription_id": "<Subscription Id>",
  "resource_group": "packt-azureml-rg",
  "workspace_name": "packt-learning-mlw"
}

对于计算实例来说,这个文件位于根文件夹(/config.json)中,并且当你在 AzureML 工作区中配置计算实例时会自动创建该文件。如果你想从本地计算机运行相同的脚本,可以创建一个类似的文件,将其放置在正在编辑的 Python 脚本旁边,然后编写以下代码来获取 AzureML 工作区的引用:

from azureml.core import Workspace
ws = Workspace.from_config()
print(f"Connected to workspace {ws.name}")

如果你想创建一个新的 AzureML 工作区,可以使用 Workspace.create() 方法来进行配置。以下代码片段将在西欧地区创建一个 AzureML 工作区:

from azureml.core import Workspace
new_ws = Workspace.create(
                   name='packt-azureml-sdk-mlw',
                   subscription_id=subscription_id,
                   resource_group='packt-azureml-sdk-rg',
                   create_resource_group=True,
                   location='westeurope')

这个代码片段将在指定 subscription_id 变量的订阅中创建一个名为 packt-azureml-sdk-mlw 的 AzureML 工作区。此资源将部署在 packt-azureml-sdk-rg 资源组中,如果该资源组不存在,将自动创建。

重要提示

Contributor role at the resource group level to be able to deploy the AzureML workspace with the SDK.

要删除你刚刚部署的工作区,可以使用以下代码片段:

new_ws.delete(delete_dependent_resources=True)

这段代码会删除由 new_ws 变量引用的工作区,并移除依赖资源,包括与 AzureML 工作区一起部署的存储账户、密钥库和应用洞察资源。

在本节中,您学习了如何通过 Python 代码引用和操作工作区资源。本节假定您一直在使用内置的笔记本编辑器,因此无需进行身份验证。如果您希望在自己的计算机上运行相同的代码,您需要进行身份验证以访问资源,这是我们将在下一节讨论的内容。

从您的设备进行身份验证

在 AzureML Studio 中的Notebooks体验需要您对计算实例进行身份验证。这是一个只需执行一次的过程,就像点击在 Notebooks 体验中可见的Authenticate按钮一样简单。如果您从本地计算机运行相同的代码,或者尝试在计算实例的终端中首次执行 Python 脚本,则必须运行 AzureML SDK 命令。一个提示将要求您进行身份验证,如下面的截图所示:

图 7.13 – 在第一个命令执行期间请求的交互式身份验证

图 7.13 – 在第一个命令执行期间请求的交互式身份验证

如果您看到此消息,请转到提供的链接,您将被要求输入提示中显示的请求代码。在这种情况下,代码是MYRNDCODE。此代码是使用您计算机位置的身份进行登录请求的唯一标识符。选择您计划用于访问各种 Azure 资源(包括 AzureML 工作区)的帐户。下图显示了整个交互式身份验证流程:

图 7.14 – 在计算实例中使用交互式登录进行身份验证

图 7.14 – 在计算实例中使用交互式登录进行身份验证

重要提示

请求代码是短暂的,有效期为 15 分钟。如果您未能在该时间段内完成过程,将会出现错误,您将需要重新开始。

如果您的帐户可以访问多个Azure Active DirectoriesAADs),例如来自试用订阅的个人 AAD 和公司的 AAD,您可能需要手动指定要进行身份验证的 AAD 租户。这可以通过使用以下片段手动调用交互式身份验证过程来完成:

from azureml.core.authentication import \ 
                             InteractiveLoginAuthentication
InteractiveLoginAuthentication(tenant_id="<AAD tenant id>")

此代码启动了设备身份验证流程,如前面的图所示。<AAD tenant id>是您可以从 Azure 门户中获取的 GUID,访问 AAD 资源时会显示。

在这一部分,你学习了交互式身份验证,它允许你从任何设备访问你的 AzureML 工作区。当你尝试在远程计算机上执行脚本,或者尝试执行 Azure CLI 命令时,应该使用这种身份验证方法。一旦身份验证完成,令牌将存储在你执行InteractiveLoginAuthentication的计算机上,直到令牌过期之前,你将无需再次登录。

在下一部分,你将开始使用已认证的工作区引用来部署计算目标,以便远程执行脚本。

使用计算目标

正如我们在第四章中提到的,配置工作区部分的配置计算资源一节所述,计算资源是允许你远程执行脚本的机器。AzureML SDK 允许你列出工作区中现有的计算目标,或者在需要时配置新的目标。

若要列出你已配置或附加到工作区的计算目标,你可以使用分配给ws变量的 AzureML 工作区引用,方法是使用ws = Workspace.from_config()。工作区对象有一个名为compute_targets的属性。它是一个 Python 字典,所有计算实例的名称作为键,而该计算实例的引用作为值。要列出并打印出此列表,你可以使用以下代码:

for compute_name in ws.compute_targets:
    compute = ws.compute_targets[compute_name]
    print(f"Compute {compute.name} is a {type(compute)}")

输出应至少列出你正在执行脚本的ComputeInstance区域,以及你在第四章中创建的AmlCompute集群,配置工作区。你会注意到所有的计算类型都在azureml.core.compute包的模块中定义。

重要提示

这段代码假设你已经初始化了ws变量,这是你在笔记本中按照使用 AzureML SDK 进行基础编码部分的指示进行的操作。如果你关闭计算实例,内核将停止,并且你通过执行笔记本单元定义的所有变量将会丢失。如果你想继续在笔记本上工作,最简单的做法是重新运行所有单元,这将确保你已初始化所有变量。

获取计算目标引用的另一种方法是使用ComputeTarget构造函数。你需要传入Workspace引用和你要查找的计算目标的名称。如果目标不存在,将引发ComputeTargetException异常,你必须在代码中处理该异常,如以下脚本所示:

from azureml.core import ComputeTarget
from azureml.exceptions import ComputeTargetException
compute_name = 'gpu-cluster'
compute = None
try:
    compute = ComputeTarget(workspace=ws, name=compute_name)
    print(f"Found {compute_name} which is {type(compute)}")
except ComputeTargetException as e:
    print(f"Failed to get compute {compute_name}. Error: {e}")

ComputeTarget类提供了create()方法,允许你配置各种计算目标,包括计算实例(ComputeInstance类)、计算集群(AmlCompute类)和 Azure Kubernetes 服务(AKSCompute类)目标。

重要提示

每当您通过 AzureML Studio Web UI、Azure CLI 或 SDK 部署计算实例或计算集群时,计算目标将被配置在与您的机器学习工作区相同的资源组和 Azure 区域内。

要配置计算目标,您需要创建一个继承自 ComputeTargetProvisioningConfiguration 抽象类的配置对象。在以下示例中,脚本尝试定位名为 cpu-sm-cluster 的计算集群。如果集群存在,则将集群的引用分配给 cluster 变量。如果集群不存在,脚本将创建 AmlComputeProvisioningConfiguration 类的实例,并将其分配给 config 变量。这个实例是通过 AmlCompute 类的 provisioning_configuration() 方法创建的。此 config 用于创建集群并等待工作区中的注册完成,显示创建日志:

from azureml.core.compute import ComputeTarget, AmlCompute
compute_name = 'cpu-sm-cluster'
cluster = None
if compute_name in ws.compute_targets:
    print('Getting reference to compute cluster')
    cluster = ws.compute_targets[compute_name]
else:
    print('Creating compute cluster')
    config = AmlCompute.provisioning_configuration(
                           vm_size='Standard_D1', 
                           max_nodes=2)
    cluster = ComputeTarget.create(ws, compute_name, config)
    cluster.wait_for_completion(show_output=True)
print(f"Got reference to cluster {cluster.name}") 

该脚本指定了虚拟机的大小(vm_size 参数)。虚拟机将设置为 Standard_D1,这是 Standard_NC6Standard_NV24s_v3Standard_ND40rs_v2。注意所有的大小都以 N 开头。

该脚本仅指定计算集群的最大节点数(max_nodes 参数)。如果未指定最小节点数(min_nodes 参数),则该参数的默认值为 0。默认情况下,集群将缩减到 0 个节点,在没有作业运行时不会产生计算成本。您可以在微软官方 Python SDK 参考页面上找到 provisioning_configuration() 方法的所有参数的默认值,如以下截图所示,或者通过执行 help(AmlCompute.provisioning_configuration) 使用 Python help 命令:

图 7.15 – AmlCompute 类的 provisioning_configuration 方法文档

图 7.15 – AmlCompute 类的 provisioning_configuration 方法文档

将计算集群的最小节点数设置为 0 的一个缺点是,您必须等待计算节点分配后,您提交的作业才会执行。为了节省这段空闲时间,通常在工作日将集群的最小节点数甚至最大节点数扩大,然后在非工作时间调整这些值以节省成本。要更改计算集群的节点数,您可以使用 AzureML Studio Web UI、Azure CLI,甚至使用以下代码更新计算集群的 min_nodes 属性:

from azureml.core.compute import AmlCompute
for ct_name, ct in ws.compute_targets.items():
    if (isinstance(ct, AmlCompute)):
        print(f"Scalling down cluster {ct.name}")
        ct.update(min_nodes=0)

重要说明

通过 AzureML Studio Web 门户、CLI、SDK 和 ARM 模板,可以更改计算集群的最小节点数和最大节点数。在 2020 年 10 月之前,您还可以通过 Azure 门户更改节点数,但该功能已被移除。

在本节中,你了解了如何创建或获取计算目标的引用,以便你可以用它来执行脚本。在下一节中,你将学习如何通过 SDK 连接到各种数据源。

定义数据存储

如我们在第四章中提到的,配置工作区部分,在连接到数据存储小节中,数据存储是存放你数据的引擎,并为授权的人员提供访问权限。AzureML SDK 允许你附加现有的数据存储以访问底层数据。

在本节中,你将把存储帐户的 Blob 容器附加到你的工作区。假设你有一个名为mydatastg的存储帐户。这个存储帐户有一个名为existing-container的 Blob 容器,里面包含你想要分析并训练模型的 CSV 文件,如下图所示:

图 7.16 – 在 Azure 门户中看到的 mydatastg 存储帐户中的容器

图 7.16 – 在 Azure 门户中看到的 mydatastg 存储帐户中的容器

重要提示

从 Azure 门户配置新的存储帐户并添加容器是一项简单的任务,超出了本考试的范围。请注意,存储帐户有唯一的名称。这意味着你可能无法创建名为mydatastg的存储帐户,因为它属于其他人。你可以使用随 AzureML 工作区一起配置的现有存储帐户来执行这些步骤。你可以通过 Azure 门户将existing-container容器添加到该存储帐户中,或者你也可以使用已经存在的azureml容器。

要将此容器注册为你的 AzureML 工作区中的新数据存储,你需要按照以下步骤操作:

  1. 在进入你的笔记本之前,你需要获取存储帐户的名称和帐户密钥。这些信息位于 Azure 门户中的设置|访问密钥选项卡下,存储帐户资源中,如下图所示:图 7.17 – 连接存储帐户所需的存储帐户名称和密钥

    图 7.17 – 连接存储帐户所需的存储帐户名称和密钥

  2. 打开你的chapter07.ipynb笔记本,在一个新的代码单元中,将这些信息赋值给以下 Python 变量:

    storage_name = 'mydatastg'
    storage_key = '<storagekey>'
    storage_container = 'existing-container'
    
  3. 要将 Blob 容器注册为一个名为my_data_store的新数据存储,你可以使用Datastore类的register_azure_blob_container()方法,如下所示:

    from azureml.core import Datastore
    dstore = Datastore.register_azure_blob_container(
        workspace=ws,
        datastore_name="my_data_store",
        container_name=storage_container,
        account_name=storage_name,
        account_key=storage_key,
        create_if_not_exists=False
    )
    

    正如预期的那样,该方法需要将Workspace区域的引用作为参数传递,新的数据存储将在该区域创建。另外,请注意,create_if_not_exists参数设置为False,这将导致方法在 Blob 容器不存在时抛出AzureMissingResourceHttpError异常,并带有ContainerNotFound的错误代码。

    与 Blob 容器类似,您可以通过 AzureML SDK 的 Datastore 类注册所有支持的数据存储类型,如以下屏幕截图所示。例如,您可以使用 register_azure_data_lake_gen2() 方法连接到 Azure 数据湖第二代数据存储,或者使用 register_azure_sql_database() 方法连接到 Azure SQL 数据库:

    图 7.18 – 来自官方文档页面的支持的数据存储服务类型

    图 7.18 – 来自官方文档页面的支持的数据存储服务类型

  4. 要获取连接的数据存储的引用,您可以使用 Datastore 类的构造函数,如以下代码片段所示:

    from azureml.core import Datastore
    dstore = Datastore.get(ws,"my_data_store")
    
  5. 第四章《配置工作区》中,在数据存储列表中,您将学习如何将注册的数据存储设置为 AzureML 工作区的默认数据存储。Workspace 类提供了一种快捷方式,可以通过 get_default_datastore() 方法引用该数据存储:

    dstore = ws.get_default_datastore()
    

    本书的其余部分,您将使用默认的数据存储来存储数据。

  6. 引用 Azure Blob 容器(AzureBlobDatastore 类)或 Azure 文件共享(AzureFileDatastore 类)的数据存储可以通过 SDK 上传和下载文件。以下代码片段加载 DataFrame,然后将其存储为本地 CSV 文件。文件存储后,脚本获取 Workspace 区域的默认数据存储的引用,该引用在 ws 变量中,并使用 upload() 方法将该文件上传到/samples/diabetes/v1/rawdata.csv

    from sklearn.datasets import load_diabetes
    import pandas as pd
    features, target = load_diabetes(return_X_y=True)
    diabetes_df = pd.DataFrame(features)
    diabetes_df['target']= target
    diabetes_df.to_csv('rawdata.csv', index=False)
    dstore = ws.get_default_datastore()
    dstore.upload_files(
                files=['rawdata.csv'],
                target_path="/samples/diabetes/v1", 
                overwrite=True,
                show_progress=True)
    
  7. 该文件将出现在与您的 AzureML 工作区一起创建的存储帐户中。您可以通过 Azure 门户找到它,方法是导航到存储帐户,选择名称以azureml-blobstore-开头的 Blob 容器,然后导航到samples / diabetes / v1文件夹,如以下屏幕截图所示:

图 7.19 – 已上传的数据存储在注册为默认数据存储的 Blob 容器中

图 7.19 – 已上传的数据存储在注册为默认数据存储的 Blob 容器中

在本节中,您学习了如何将现有的 Azure Blob 容器附加到 AzureML 工作区中的新数据存储。您还学习了如何轻松获取工作区默认数据存储的引用,然后将 CSV 文件上传到该数据存储。在下一节中,您将学习如何定义数据集,这一构建可以帮助您独立于数据存储位置进行数据操作。

使用数据集

正如我们在第四章,《配置工作区》一节中提到的,在《使用数据集》部分中,数据集是你在训练和推理过程中使用的一个抽象层。它们包含对物理数据位置的引用,并提供一系列元数据,帮助你理解数据的形状和统计特性。数据集不会复制存储在数据存储中的数据。AzureML 提供了两种类型的数据集:

  • FileDataset允许你引用一个或多个文件,存储在一个或多个数据存储中。FileDataset的一个常见例子是用于训练计算机视觉模型的图像。

  • TabularDataset允许你引用存储在一个文件或多个文件中的表格结构数据,这些文件可能存储在数据存储中,或者直接存储在像 SQL 服务器这样的关系型数据存储中。你在上一节中加载的糖尿病DataFrame就是一个典型的表格数据集。你可以通过解析各种文件(包括 CSV、TSV、Parquet 和 JSON 文件)来创建TabularDataset。如果你的数据包含一个带有时间戳的列/特征,或者文件存储在包含日期模式的文件夹结构中,比如/<year>/<month>/file.csv,你可以启用TabularDataset的时间序列特性,这样可以进行基于时间的数据集筛选。

为了获得一些实际操作经验,你可以定义一个FileDataset,它引用了你在上一节中上传的默认数据存储中的 CSV 文件。虽然 CSV 表示表格数据,但它也可以是一个文件,FileDataset可以引用这样的文件。

  1. 在你的笔记本中新建一个单元格,输入以下代码:

    from azureml.core import Dataset
    dstore = ws.get_default_datastore()
    file_paths = [
        (dstore, "/samples/diabetes/v1")
    ]
    file_ds = Dataset.File.from_files(
        path = file_paths, validate=True
    )
    print("Files in FileDataset:")
    print(file_ds.to_path())
    

    在这段代码中,引用了工作站的默认数据存储。

  2. 现在,你可以创建一个包含Datastore及其相对路径的元组数组。每个元组引用一个特定Datastore中的文件或文件夹。在这种情况下,你引用的是默认Datastore中的samples/diabetes/v1文件夹。如果你愿意,可以使用通配符字符*来加载多个子文件夹或部分文件名。例如,以下元组数组加载了 2021 年所有月份的天气数据 CSV 文件,这些文件存储在/weather/<year>/<month>/<day>.csv路径下:

    file_paths = [
        (dstore, "/weather/2021/*/*.csv")
    ]
    
  3. 如果你只想显式加载 1 月(01.csv)、2 月(02)、和 3 月(03)的第一天数据,你可以使用以下元组数组:

    file_paths = [
        (dstore, "/weather/2021/01/01.csv"),
        (dstore, "/weather/2021/02/01.csv"),
        (dstore, "/weather/2021/03/01.csv")
    ]
    

    出于性能考虑,建议每个数据集的数组大小不要超过 100 个数据路径引用。

  4. 返回到本节开头的代码片段,现在您可以使用from_files()方法创建一个未注册的FileDataset。在此处,您必须将数据路径数组作为参数传递。您还必须验证数据是否可以通过该方法加载。如果文件夹不存在或数据存储由于私有端点受保护,不可直接从执行代码的计算资源访问,则会收到DatasetValidationErrorvalidate参数的默认值为True,您可以通过在该参数中传递False来禁用该验证。

  5. 创建了FileDataset之后,您可以通过调用to_path()方法获取被引用的文件列表。这两个打印的输出应如下所示:图 7.20 – 未注册的 FileDataset 引用单个 CSV 文件

    图 7.20 – 未注册的 FileDataset 引用单个 CSV 文件

  6. 对于 CSV 文件,更好的方法是定义一个TabularDataset,它可以解析文件并为我们提供 pandas DataFrame。为此,请将以下代码复制到一个新单元格中:

    tabular_dataset = Dataset.Tabular.from_delimited_files(
        path=file_paths, validate=False)
    df = tabular_dataset.to_pandas_dataframe()
    print(len(df))
    

    在此片段中,您正在重用创建FileDataset时使用的file_paths属性。这次,您正在使用from_delimited_files()方法创建一个未注册的TabularDataset。还请注意,您明确跳过验证,以便可以从当前计算资源加载数据(validate=False),加快声明过程。

    DataFrame,并在调用to_pandas_dataframe()方法时将其分配给df变量。调用len()方法时,您可以获取DataFrame的行数。

  7. 到目前为止,您创建的数据集都是未注册的,这意味着它们未在 AzureML 工作区中注册,也未在register()方法中列出:

    tabular_dataset.register(
        workspace=ws,
        name="diabetes",
        description="The sklearn diabetes dataset")
    

    重要提示

    如果您已经注册了同名的数据集,则无法重新运行此单元格。要注册数据集的新版本,必须使用以下方式使用create_new_version参数:tabular_dataset.register(workspace=ws, name="diabetes", create_new_version=True)

    此方法要求您指定要注册TabularDataset的工作区以及注册的名称。可选地,您可以传递描述、标签以及是否要使用已在工作区中注册的特定名称创建数据集的新版本。数据集注册后,您可以在 Studio Web UI 中查看注册信息,如下截图所示:

    图 7.21 – 注册在工作区中的表格数据集

    图 7.21 – 注册在工作区中的表格数据集

  8. 如果您有一个 pandas DataFrame 而不是TabularDataset,并且想要注册它,可以使用register_pandas_dataframe()方法,如下面的代码片段所示:

    Dataset.Tabular.register_pandas_dataframe(
        dataframe=df,
        target=(dstore,"/samples/diabetes"),
        name="diabetes",
        description="The sklearn diabetes dataset")
    

    请注意,在这个代码片段中,你传递了 df pandas DataFrame 引用,并且请求将该 DataFrame 存储在由 dstore 变量引用的默认数据存储中,存储路径为 /samples/diabetes 文件夹。此方法将创建一个具有 GUID 名称的新文件夹,并将数据以 Parquet 文件格式存储。由于数据集已经注册并指向不同的路径,该命令将创建数据集的新版本。在 Studio 界面中,你会看到 版本 2 的数据集已被注册。这个版本有一个不同的 相对路径,如下面所示:

    图 7.22 – 从 pandas DataFrame 直接注册的新版本糖尿病数据集

    图 7.22 – 从 pandas DataFrame 直接注册的新版本糖尿病数据集

    请注意,Parquet 文件格式是一种压缩格式,与用于数据集第一版的 CSV 文件相比,它的文件体积更小。

  9. 注册数据集后,无论是 FileDataset 还是 TabularDataset,你都可以使用 Dataset 类的 get_by_name() 方法来检索它,使用如下代码片段:

    from azureml.core import Dataset
    diabetes_dataset = Dataset.get_by_name(
        workspace=ws,
        name='diabetes')
    

    可选地,你可以指定 version 参数,默认值为 latest

  10. 上面的代码片段返回一个 TabularDataset 类的实例,但数据尚未加载。你可以通过 TabularDataset 类的各种方法部分加载数据集,如下所示的代码片段所示:

    partial_dataset = diabetes_dataset \
            .skip(10) \
            .take(2) \
            .keep_columns(['0','target'])
    
  11. partial_dataset 是从 diabetes_dataset 创建的 TabularDataset 实例。该数据集跳过了 diabetes_dataset 的前 10 行,保留了两行,并删除了所有列,除了名为 0target 的列。在执行此多行语句时没有加载任何数据。定义了这个未注册的 partial_dataset 数据集后,你可以使用以下代码将数据加载到 pandas DataFrame 中:

    df = partial_dataset.to_pandas_dataframe()
    df.head()
    

    这将显示一个由两行两列组成的小型表格,如下所示的屏幕截图所示:

图 7.23 – 从切片表格数据集加载的小型 DataFrame

图 7.23 – 从切片表格数据集加载的小型 DataFrame

AzureML 数据集类的惰性加载功能让你可以灵活地对庞大的数据集进行切片和操作,而无需将其加载到内存中。

到目前为止,你已经学习了如何使用 Python SDK 部署计算目标、定义数据存储和创建数据集。在下一节中,你将学习如何使用在第二章中看到的 Azure CLI 工具执行类似操作,部署 Azure 机器学习工作区资源,该章节位于 使用 Azure CLI 部分。

使用 AzureML CLI 扩展

第二章部署 Azure 机器学习工作区资源》中,你学习了如何使用 Azure CLI,以及如何安装azure-cli-ml扩展。这个扩展使用你在本章看到的 Python SDK 执行各种操作。要使用 Azure CLI,你可以选择以下任一方法:

  1. 打开 Azure 门户中的云终端,就像你在第二章部署 Azure 机器学习工作区资源》中所做的那样。

  2. 打开你在本章中使用的计算实例的终端。

  3. 使用 Jupyter 笔记本的 shell 分配功能,允许你通过使用感叹号(!),也叫做bang,执行底层 shell 命令。

在本节中,你将使用笔记本,这将帮助你存储步骤,并在未来需要时重复这些步骤:

  1. 首先,你需要在你当前正在使用的计算实例的 Azure CLI 中安装azure-cli-ml扩展。创建一个新的代码单元格,并添加以下代码:

    ! az extension add -n azure-cli-ml
    

    请注意,在第二章部署 Azure 机器学习工作区资源》中,你执行了相同的命令,但没有感叹号前缀。此命令的输出应类似于以下内容:

    图 7.24 – 安装 AzureML 扩展

    图 7.24 – 安装 AzureML 扩展

  2. 然后,你需要使用az login命令登录。此命令将触发设备认证过程,类似于你在本章开始时尝试通过 SDK 连接到工作区时使用的认证方式。运行以下命令:

    ! az login
    
  3. 如果你有多个 Azure 订阅的访问权限,你需要使用以下代码片段选择你正在使用的订阅:

    ! az account set --subscription "<subscription id>"
    

    从现在开始,你可以使用 AzureML CLI 对工作区执行操作。

    重要提示

    如果你在订阅中有多个 AzureML 工作区,你需要指定每个 AzureML CLI 命令的目标工作区和资源组。为此,你需要使用-g-w参数,我们在第二章部署 Azure 机器学习工作区资源》中已经介绍过。

  4. 要列出工作区中的所有计算目标,可以使用以下代码片段:

    ! az ml computetarget list -g packt-azureml-rg -w packt-learning-mlw -o table
    
  5. 然后,你可以使用以下命令更新cpu-sm-cluster,使其具有 0 个最小节点:

    ! az ml computetarget update amlcompute --name cpu-sm-cluster --min-nodes 0 -g packt-azureml-rg -w packt-learning-mlw
    
  6. 要获取在工作区中注册的默认数据存储,可以使用以下命令:

    ! az ml datastore show-default -g packt-azureml-rg -w packt-learning-mlw
    
  7. 最后,你可以使用以下代码列出工作区中注册的数据集:

    ! az ml dataset list -g packt-azureml-rg -w packt-learning-mlw -o table
    

    该命令的结果应类似于以下内容:

图 7.25 – 在 AzureML CLI 中列出的数据集表格格式输出

图 7.25 – AzureML CLI 中数据集列表的表格格式输出

AzureML CLI 提供对 SDK 选项的完全访问权限,包括创建和分离计算目标、数据存储,甚至定义数据集的能力。对于考试,您不需要记住命令,只要您理解 CLI 在后台使用 SDK,并且大多数您可以用 SDK 做的事情都有对应的 CLI 命令即可。

总结

在本章中,您学习了 AzureML Python SDK 的结构。您还发现了 AzureML 笔记本编辑器,允许您编写 Python 脚本。接着,您使用了 SDK,并开始通过管理附加到 AzureML 工作区的计算目标来启动编码旅程。然后,您附加了新的数据存储并获取了现有数据存储的引用,包括工作区的默认数据存储。接下来,您处理了各种文件和基于表格的数据集,并学习了如何通过将它们注册到工作区中来重用这些数据集。

最后,您已经使用了 AzureML CLI 扩展,这是一个客户端,利用了您在本章中探索的 Python SDK。

在下一章中,您将基于这些知识进一步学习如何在数据科学实验阶段使用 AzureML SDK。您还将学习如何跟踪数据科学实验中的指标,并了解如何通过在计算集群中运行脚本来将训练扩展到更大的计算资源。

问题

请回答以下问题,以检查您对本章所讨论的主题的理解:

  1. AzureML 计算集群的默认最小节点数是多少?

    a. 0

    b. 1

    c. 等于最大节点数

  2. 您将一个包含信用卡交易详情的 CSV 文件上传到默认数据存储库。您应该使用以下哪种方法来创建数据集引用?

    a. Dataset.File.from_files()

    b. Dataset.Tabular.from_delimited_files()

    c. Workspace.from_csv_files()

    d. Datastore.from_csv_files()

  3. 如何在注册 Azure Blob 存储数据存储库的过程中强制创建 Blob 容器?

    a. 将 force_create=True 参数传递给 Datastore.register_azure_blob_container() 方法。

    b. 将 create_if_not_exists=True 参数传递给 Datastore.register_azure_blob_container() 方法。

    c. 将 force_create=True 参数传递给 Datastore.register_container() 方法。

    b. 将 create_if_not_exists=True 参数传递给 Datastore.register_container() 方法。

进一步阅读

本节提供了一些有用的网络资源,这些资源将帮助您增强对 AzureML SDK 及本章中使用的各种第三方库的知识:

第八章:第八章:使用 Python 代码进行实验

在本章中,你将了解如何训练 scikit-learn 库,它通常被称为 sklearn。你将了解如何使用Azure 机器学习AzureMLSDKMLflow 来跟踪训练指标。接着,你将看到如何在计算集群中扩展训练过程。

本章将涵盖以下主题:

  • 在笔记本中训练一个简单的 sklearn 模型

  • 在实验中跟踪指标

  • 扩展训练过程与计算集群

技术要求

你需要有一个 Azure 订阅。在该订阅下,你需要有一个 packt-azureml-rg。你还需要有 ContributorOwner 权限的 packt-learning-mlw。如果你按照第二章《部署 Azure 机器学习工作区资源》中的说明进行操作,这些资源应该已经为你准备好了。

你还需要具备 Python 语言的基础知识。本章中的代码片段适用于 Python 3.6 或更高版本。你还应熟悉在 AzureML Studio 中使用笔记本的操作体验,这部分内容已在上一章中讲解过。

本章假设你已经在 AzureML 工作区中注册了 scikit-learndiabetes 数据集,并且已经创建了一个名为 cpu-sm-cluster 的计算集群,正如在第七章《AzureML Python SDK》中的 定义数据存储处理数据集使用计算目标 部分所描述的那样。

你可以在 GitHub 上找到本章的所有笔记本和代码片段,链接:bit.ly/dp100-ch08

在笔记本中训练一个简单的 sklearn 模型

本节的目标是创建一个 Python 脚本,在你在第七章中注册的diabetes数据集上,训练出一个简单的模型,《AzureML Python SDK》。该模型将获取数字输入,并预测一个数字输出。为了创建这个模型,你需要准备数据、训练模型、评估训练模型的表现,然后将其存储,以便未来可以重用,正如在图 8.1中所示:

图 8.1 - 生成糖尿病预测模型的过程

图 8.1 - 生成糖尿病预测模型的过程

让我们从了解你将要使用的数据集开始。diabetes 数据集包含 442 名diabetes患者的数据。每一行代表一个患者。每一行包含 10 个特征(target,是记录特征后 1 年糖尿病病情发展的定量指标)。

你可以在 AzureML Studio 界面中进一步探索数据集,正如在图 8.2中所示:

图 8.2 – 注册的糖尿病数据集

图 8.2 – 已注册的糖尿病数据集

通常在准备阶段,您会加载原始数据,处理缺失值的行,规范化特征值,然后将数据集分为训练数据和验证数据。由于数据已经预处理,您只需加载数据并将其拆分为两个部分:

  1. 导航到chapter08,然后创建一个名为chapter08.ipynb的笔记本:图 8.3 – 创建您将要使用的 chapter08 笔记本

    图 8.3 – 创建您将要使用的 chapter08 笔记本

  2. 在笔记本的第一个单元格中,添加以下代码:

    from azureml.core import Workspace
    ws = Workspace.from_config()
    diabetes_ds = ws.datasets['diabetes']
    training_data, validation_data =\
    diabetes_ds.random_split(percentage = 0.8)
    X_train =\
    training_data.drop_columns('target').to_pandas_dataframe()
    y_train =\
    training_data.keep_columns('target').to_pandas_dataframe()
    X_validate =\
    validation_data.drop_columns('target').to_pandas_dataframe()
    y_validate =\
    validation_data.keep_columns('target').to_pandas_dataframe()
    

    在此代码片段中,您获取工作区的引用并检索名为diabetes的数据集。然后,您使用random_split()方法将其拆分为两个TabularDataset。第一个数据集是training_data,它包含 80%的数据,而validation_data数据集引用其余 20%的数据。这些数据集包含您要预测的特征和标签。使用TabularDatasetdrop_columns()keep_columns()方法,您可以将特征与label列分开。然后,您通过TabularDatasetto_pandas_dataframe()方法将数据加载到内存中。最终,您将得到四个 pandas 数据框:

    • X_train:包含 80%的行,每行有 10 列(09)。

    • y_train:包含 80%的行,每行有 1 列(target)。

    • X_validate:包含 20%的行,每行有 10 列(09)。

    • y_validate:包含 20%的行,每行有 1 列(target)。

    diabetes数据集在科学文献中非常流行。它被用作训练回归模型的示例。scikit-learn库提供了一个名为sklearn.linear_model的专用模块,包含许多线性回归模型可供我们使用。现在您已经准备好了数据,接下来的任务是训练模型。

  3. 在此步骤中,您将训练一个LassoLars模型,它是LassoLars类的缩写,该类接受一个名为alpha的浮动参数,该参数被称为正则化参数惩罚项。它的主要目的是保护模型免受训练数据集的过拟合。由于该参数控制训练过程,因此被称为超参数。一旦模型训练完成,这个参数不能再更改。在这个代码块中,您正在实例化一个未训练的模型,并将alpha参数设置为0.1。在下一章,第九章优化机器学习模型,您将调整此参数,并尝试为您的数据集找到最佳值。

    然后,您将使用X_trainy_train数据框来 fit()模型,这意味着您正在用训练数据集训练模型。经过这个过程后,model变量引用一个已训练的模型,您可以使用该模型进行预测。

  4. 接下来的任务是基于某个指标评估你所生成的模型。评估回归模型时最常用的指标如下:

    • 平均或中位数绝对误差。

    • 均方误差或对数误差。该指标的另一种常见变体是sklearn.metrics包中的mean_squared_error方法。该指标的常见问题是,当模型在具有更大值范围的数据上训练时,相比于在较小值范围的数据上训练的同一模型,其误差率更高。你将使用一种称为指标归一化的技术,该技术基本上是将指标除以数据的范围。计算得到的指标被称为X_validate数据框。你通过将预测结果与存储在y_validate数据框中的真实值进行比较,来计算 RMSE。接着,你使用ptp()方法计算值的范围(最大值减去最小值),得到0.2

      最后一步是将训练好的模型存储起来,以便将来能够重用。你将创建一个名为outputs的文件夹,并将模型持久化到一个文件中。Python 对象的持久化通过joblib库的dump()方法完成。

      在新的笔记本单元格中,输入以下源代码:

      import os
      import joblib
      os.makedirs('./outputs', exist_ok=True)
      model_file_name = f'model_{nrmse:.4f}_{alpha:.4f}.pkl'
      joblib.dump(value=model,
              filename=os.path.join('./outputs/',model_file_name))
      

      如果outputs文件夹不存在,你需要先创建它。然后,将模型存储在包含model_前缀的文件名中,后跟在步骤 4中计算的 NRMSE 指标,再加上一个_,然后是用于实例化模型的alpha参数。你应该能够在文件资源管理器中看到序列化的模型,如图 8.4所示:

图 8.4 – 序列化模型存储在输出文件夹中

图 8.4 – 序列化模型存储在输出文件夹中

你在步骤 5中使用的命名规范帮助你跟踪模型的表现,以及记录你在本次运行中使用的参数。AzureML SDK 提供了多种方法来监控、组织和管理你的训练过程,这些内容你将在下一节中探讨。

在实验中跟踪指标

当你训练一个模型时,你是在进行一个试验,并且你正在记录该过程的各个方面,包括你需要比较模型表现的 NRMSE 等指标。AzureML 工作区提供了实验的概念——即用于将这些试验/运行归类的容器。

要创建一个新的实验,只需要指定你将使用的工作区,并提供一个包含最多 36 个字母、数字、下划线和破折号的名称。如果实验已经存在,你将获得对它的引用。在你的chapter08.ipynb笔记本中添加一个单元格,并添加以下代码:

from azureml.core import Workspace, Experiment
ws = Workspace.from_config()
exp = Experiment(workspace=ws, name="chapter08")

你首先获取现有 AzureML 工作区的引用,然后创建chapter08实验(如果它还不存在的话)。如果你导航到 Studio 界面中的资产 | 实验部分,你会注意到列表中会出现一个空的实验,如图 8.5所示:

图 8.5 – 使用 SDK 创建的空实验

图 8.5 – 使用 SDK 创建的空实验

要在chapter08实验下创建一个run,你可以在新的单元格中添加以下代码:

run = exp.start_logging()
print(run.get_details())

run变量允许你访问 AzureML SDK 的Run类实例,该实例代表实验的单个试验。每个run实例都有一个唯一的 ID,用于标识工作区中特定的运行。

重要提示

扩展训练过程与计算集群部分中,你将使用Run类的get_context方法来获取当前执行 Python 脚本的run实例的引用。通常,当你提交脚本在实验下执行时,run会自动创建。start_logging方法较少使用,仅在你需要手动创建一个run并记录度量时使用。最常见的情况是你使用笔记本单元格来训练模型,或者在远程计算环境(如本地计算机或Databricks工作区)上训练模型时。

run类提供了丰富的日志记录 API。最常用的方法是通用的log()方法,它允许你通过以下代码记录度量:

run.log("nrmse", 0.01)
run.log(name="nrmse", value=0.015, description="2nd measure")

在这段代码中,你记录了nrmse度量的值0.01,然后记录了同一度量的值0.015,并传递了可选的description参数。

如果你进入chapter08实验,你会注意到目前有一个正在运行的run,并且当你切换到Metrics标签时,你会看到nrmse度量的两个测量值,以图表或表格的形式呈现,正如图 8.6所示:

图 8.6 – 在 Studio 体验中看到的 nrmse 的两个测量值

图 8.6 – 在 Studio 体验中看到的 nrmse 的两个测量值

Run类提供了丰富的日志记录方法,包括以下几种:

  • log_list方法允许你为特定度量记录一系列值。该方法的示例如下代码:

    run.log_list("accuracies", [0.5, 0.57, 0.62])
    

    这段代码将在runMetrics部分生成图 8.7

图 8.7 – 使用 log_list 方法记录的三个值的图表

图 8.7 – 使用 log_list 方法记录的三个值的图表

  • log_tablelog_row方法允许你记录表格数据。请注意,使用此方法时,你可以指定与log_list方法不同的X轴标签:

    run.log_table("table", {"x":[1, 2], "y":[0.1, 0.2]})
    run.log_row("table", x=3, y=0.3)
    

    这段代码片段将在runMetrics部分生成图 8.8

图 8.8 – 使用 log_table 和 log_row 方法记录的表格度量

图 8.8 – 使用 log_table 和 log_row 方法记录的表格度量

  • 专门的方法如log_accuracy_tablelog_confusion_matrixlog_predictionslog_residuals提供了日志数据的自定义呈现。

  • log_image方法允许你从著名的matplotlib Python 库或其他绘图库记录图形或图像。

  • upload_fileupload_filesupload_folder方法允许你上传实验残留文件并将其与当前运行关联。这些方法通常用于上传在run执行过程中生成的各种二进制工件,例如由开源库如plotly创建的交互式 HTML 图形。

你可以选择创建子运行以隔离试验的一个子部分。子运行记录它们自己的度量指标,你也可以选择登录到父运行。例如,以下代码段创建一个子运行,记录一个名为child_metric的度量(该度量仅在该运行中可见),然后在父运行的度量中记录metric_from_child

child_run = run.child_run()
child_run.log("child_metric", 0.01)
child_run.parent.log("metric_from_child", 0.02)

一旦你完成了运行,你需要更改其运行中状态。你可以使用以下方法之一:

  • complete方法表示运行已成功完成。此方法还会将outputs文件夹(如果存在)上传到runs工件中,而无需显式调用Run类的upload_folder方法。

  • cancel方法表示作业已被取消。你会注意到在 AutoML 实验中运行被取消,因为超出了超时限制。

  • 已弃用的fail方法表示发生了错误。

以下代码段取消了子运行并完成了根运行,打印状态,应该显示已完成

child_run.cancel()
run.complete()
print(run.get_status())

在这一部分,你了解了 AzureML 的日志记录功能。在下一部分,你将重构你在在笔记本中训练简单的 sklearn 模型部分编写的代码,并添加日志记录功能。

跟踪模型演化

在前面的部分,你可能已经注意到,当你执行complete方法时,本章在笔记本中训练简单的 sklearn 模型部分中创建的outputs文件夹会自动上传到运行中。为了避免上传那些过时的工件,你需要删除outputs文件夹:

  1. 在你的chapter08.ipynb笔记本中添加一个单元格,并使用以下代码段删除outputs文件夹:

    import shutil
    try:
      shutil.rmtree("./outputs")
    except FileNotFoundError: 
      pass
    
  2. 下一步,你将把训练和评估的代码重构为一个单独的方法,传入alpha参数以及trainingvalidation数据集:

    from sklearn.linear_model import LassoLars
    from sklearn.metrics import mean_squared_error
    def train_and_evaluate(alpha, X_t, y_t, X_v, y_v):
      model = LassoLars(alpha=alpha)
      model.fit(X_t, y_t)
      predictions = model.predict(X_v)
      rmse = mean_squared_error(predictions, y_v, squared = False)
      range_y_validate = y_v.to_numpy().ptp()
      nrmse = rmse/range_y_validate
      print(f"NRMSE: {nrmse}")
      return model, nrmse
    trained_model, model_nrmse = train_and_evaluate(0.1, 
                            X_train, y_train,
                            X_validate, y_validate) 
    

    这段代码与你在在笔记本中训练简单的 sklearn 模型部分编写的代码完全相同。现在,你可以通过使用train_and_evaluate并传入不同的alpha参数值来训练多个模型,这个过程被称为超参数调优。在这段代码的最后一行,你将获得训练好的模型及其 NRMSE 度量的引用。

    重要提示

    如果你遇到以下错误:NameError: name 'X_train' is not defined,你需要重新运行你定义了X_trainy_trainX_validatey_validate变量的单元格。这表示 Python 内核已经重启,所有变量都已从内存中丢失。

    到目前为止,你已经重构了现有代码并保持了相同的功能。为了启用通过前一部分中探索的Run类进行日志记录,你需要将当前运行实例的引用传递给train_and_evaluate方法。

  3. 在一个新的单元格中,添加以下代码片段,它将覆盖现有的train_and_evaluate方法声明:

    def train_and_evaluate(log and log_row methods to log the NRMSE metric of the trained model.Important noteIf you cannot type the *α* letter shown in the preceding example, you can use the *a* character instead.
    
  4. 拥有这个train_and_evaluate方法后,你可以进行超参数调优,并为多个αalpha)参数值训练多个模型,使用以下代码:

    from azureml.core import Workspace, Experiment
    ws = Workspace.from_config()
    exp = Experiment(workspace=ws, name="chapter08")
    with exp.start_logging() as run:
        print(run.get_portal_url())
        for a in [0.001, 0.01, 0.1, 0.25, 0.5]:
            train_and_evaluate(run, a, 
                                X_train, y_train,
                                X_validate, y_validate)
    

    注意,我们没有调用complete方法,而是使用了with .. as的 Python 设计模式。随着run变量超出作用域,它会自动标记为已完成。

  5. 步骤 4中使用get_portal_url,你打印了指向工作室的log方法调用的链接,而αalpha)参数是你使用log_row方法记录的内容。你应该看到类似于图 8.9所示的图表:

![图 8.9 – 糖尿病模型的 nrmse 指标演变]

](https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/az-ds-ass-cert-gd/img/B16777_08_009.jpg)

图 8.9 – 糖尿病模型的 nrmse 指标演变

重要提示

在本节中,你仅仅将指标存储在Run实例中,而不是实际的训练模型。你本可以通过生成.pkl文件并使用upload_file方法将其上传到运行的工件中来存储生成的模型。在第十二章使用代码实现模型操作,你将学习 AzureML SDK 的模型注册功能,它提供了一种更优的体验来跟踪实际模型。

在本节中,你看到了如何使用 AzureML SDK 启用指标日志记录。在跟踪实验指标方面,数据科学界使用了一个流行的开源框架——MLflow。在下一节中,你将学习如何使用该库在 AzureML 工作区中跟踪指标。

使用 MLflow 跟踪实验

MLflow 库是一个流行的开源库,用于管理数据科学实验的生命周期。该库允许你将工件和指标存储在本地或服务器上。AzureML 工作区提供了一个 MLflow 服务器,你可以用它来做以下事情:

  • 通过MLflow 跟踪组件跟踪和记录实验指标。

  • 通过MLflow 项目组件在 AzureML 计算集群上协调代码执行(类似于你将在第十一章中看到的管道,与管道合作)。

  • 在 AzureML 模型注册表中管理模型,你将在第十二章《用代码实现模型运营化》中看到该内容。

本节将重点介绍 MLflow Tracking 组件,用于跟踪度量。以下代码片段使用MLflow库跟踪你在前一节中创建的diabetes模型的参数和度量,实验名称为chapter08-mlflow

import mlflow
def train_and_evaluate(alpha, X_t, y_t, X_v, y_v):
  model = LassoLars(alpha=alpha)
  model.fit(X_t, y_t)
  predictions = model.predict(X_v)
  rmse = mean_squared_error(predictions, y_v, squared = False)
  range_y_validate = y_v.to_numpy().ptp()
  nrmse = rmse/range_y_validate
  mlflow.log_metric("nrmse", nrmse)
  return model, nrmse
mlflow.set_experiment("chapter08-mlflow")
with mlflow.start_run():
    mlflow.sklearn.autolog()
    trained_model, model_nrmse = train_and_evaluate(0.1, 
                                    X_train, y_train,
                                    X_validate, y_validate)

MLflow Tracking 组件最著名的特点之一是其提供的自动日志记录功能。在训练代码之前调用mlflow.sklearn.autolog()方法,可以自动记录sklearn的度量、参数和生成的模型。类似于sklearn特定的autolog方法,常见训练框架(如 PyTorch、fast.ai、Spark 等)也有对应的包。

使用log_metric方法,你显式地要求 MLflow 库记录一个度量。在此示例中,你记录了 NRMSE 度量,该度量不会通过自动日志记录功能自动捕获。

正如图 8.10所示,MLflow Tracking 组件将所有工件和训练模型以文件夹结构记录在mlruns文件夹中,紧邻笔记本文件。

图 8.10 – 使用 MLflow Tracking 组件的本地 FileStore 模式跟踪度量

图 8.10 – 使用 MLflow Tracking 组件的本地 FileStore 模式跟踪度量

这是默认设置,称为本地 FileStore。你可以将 AzureML 工作区用作远程跟踪服务器。为此,你需要使用mlflow.set_tracking_uri()方法连接到一个跟踪 URI。

要启用 MLflow 与 AzureML 的集成,你需要确保环境中安装了azureml-mlflow Python 库。该库已包含在 AzureML 计算实例中。如果你在 Databricks 工作区中工作,则需要通过pip install azureml-mlflow命令手动安装。

要获取跟踪URI并使用 AzureML 作为远程跟踪服务器运行相同的实验,请使用以下代码片段:

import mlflow
from azureml.core import Workspace
ws = Workspace.from_config()
mlflow.set_tracking_uri(ws.get_mlflow_tracking_uri())
mlflow.set_experiment("chapter08-mlflow")
with mlflow.start_run():
    mlflow.sklearn.autolog()
    trained_model, model_nrmse = train_and_evaluate(0.1, 
                                    X_train, y_train,
                                    X_validate, y_validate)

Workspace类的get_mlflow_tracking_uri方法返回一个有效期为 1 小时的 URL。如果你的实验超过一小时仍未完成,你将需要生成新的 URI,并使用set_tracking_uri方法将其分配,如前面代码片段所示。

你应该能够在 Studio 界面中看到运行情况和已跟踪的度量,如图 8.11所示:

图 8.11 – 使用 MLflow 库并将 AzureML 用作远程跟踪服务器时记录的度量

图 8.11 – 使用 MLflow 库并将 AzureML 用作远程跟踪服务器时记录的度量

到目前为止,你一直在使用 AzureML 工作区中的计算实例,并且你是在Notebook内核中训练 ML 模型。对于小型模型或在示例数据上快速原型开发,这种方法效果很好。但在某些时候,你将需要处理更高负载的工作负载,这可能涉及更大的内存要求,甚至是在多个计算节点上进行分布式训练。你可以通过将训练过程委托给在第四章中创建的计算集群来实现这一目标,配置工作区。在下一节中,你将学习如何在 AzureML 计算集群中执行 Python 脚本。

使用计算集群扩展训练过程

第七章AzureML Python SDK中,你创建了一个名为cpu-sm-cluster的计算集群。在这一节中,你将提交一个训练任务以在该集群上执行。为此,你需要创建一个将在远程计算目标上执行的 Python 脚本。

导航到你迄今为止正在使用的chapter08文件夹中的greeter-job。添加一个名为greeter.py的 Python 文件:

图 8.12 – 向远程计算集群添加简单的 Python 脚本以执行

图 8.12 – 向远程计算集群添加简单的 Python 脚本以执行

打开该文件并添加以下代码:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--greet-name', type=str, 
                    dest='name', help='The name to greet')
args = parser.parse_args()
name = args.name
print(f"Hello {name}!")

该脚本使用argparse模块中的ArgumentParser类来解析传递给脚本的参数。它试图查找一个--greet-name参数,并将找到的值分配给它返回的对象的name属性(args.name)。然后,它会打印出给定名称的问候消息。要尝试这个脚本,请打开终端并输入以下命令:

python greeter.py --greet-name packt

这个命令将产生如下所示的输出,如图 8.13所示:

图 8.13 – 测试你将在远程计算机上执行的简单脚本

图 8.13 – 测试你将在远程计算机上执行的简单脚本

为了在远程计算集群上执行这个简单的 Python 脚本,请返回到chapter08.ipynb笔记本,添加一个新单元,并输入以下代码:

from azureml.core import Workspace, Experiment
from azureml.core import ScriptRunConfig
ws = Workspace.from_config()
target = ws.compute_targets['cpu-sm-cluster']
script = ScriptRunConfig(
    source_directory='greeter-job',
    script='greeter.py',
    compute_target=target,
    arguments=['--greet-name', 'packt']
)
exp = Experiment(ws, 'greet-packt')
run = exp.submit(script)
print(run.get_portal_url())
run.wait_for_completion(show_output=True)

在这段代码中,你正在执行以下操作:

  1. 获取工作区的引用,然后将target变量分配给cpu-sm-cluster集群的引用。

  2. 创建一个ScriptRunConfig,以执行位于greeter-job文件夹中的greeter.py脚本。该脚本将在target计算机上执行,并传递--greet-namepackt参数,它们将通过空格连接起来。

  3. 创建一个名为greet-packt的实验,并将脚本配置提交以在该实验下执行。submit方法创建了一个新的Run实例。

  4. 你可以使用get_portal_url方法获取特定Run实例的门户 URL。然后调用wait_for_completion方法,将show_output参数设置为True。为了等待运行完成,开启详细日志记录,并在单元格的输出中打印日志。

    重要说明

    在 AzureML SDK 的第一个版本中,你会使用Estimator类,而不是ScriptRunConfig,但该类已被弃用。此外,还有一些针对特定框架的已弃用专用Estimator类,例如TensorFlow类,它提供了一种运行特定于 TensorFlow 的代码的方式。这种方法已经被弃用,取而代之的是你将在下面的理解执行环境部分中阅读到的环境。然而,这些已弃用类的语法和参数与ScriptRunConfig非常相似。你应该能够毫无问题地阅读这些已弃用的代码。如果在认证考试中看到关于这些已弃用类的旧问题,记得这一点。

你已经成功完成了远程执行的运行。在下一部分,你将探索刚刚完成的运行日志,更好地理解 AzureML 的机制。

探索运行的输出和日志

在这一部分,你将探索在使用计算集群扩展训练过程部分中执行的远程执行输出。这将帮助你深入了解 AzureML 平台的工作原理,并帮助你排查在开发训练脚本时可能遇到的潜在错误。

使用get_portal_url方法打开你在前一部分中打印的链接,或者导航到greet-packt实验并打开Run 1。进入该运行的Outputs + logs标签页:

图 8.14 – 实验运行的 Outputs + logs 标签页

图 8.14 – 实验运行的 Outputs + logs 标签页

这些输出对于排查潜在的脚本错误非常有帮助。azureml-logs文件夹包含平台日志。这些文件大部分是底层引擎的日志。包含你脚本标准输出的日志是70_driver_log.txt。这是你需要首先查看的日志文件,用于排查潜在的脚本执行失败。如果你有多个进程,你会看到多个带有数字后缀的文件,如70_driver_log_x.txt

logs文件夹是你可以在脚本中使用的特殊文件夹,用于输出日志。脚本写入该文件夹的所有内容会自动上传到你在实验中跟踪指标部分中看到的运行outputs文件夹。AzureML 还会在该文件夹下的azureml文件夹中输出系统日志,如图 8.14所示。

导航到ScriptRunConfig。该目录可以包含最多 300MB 的内容和最多 2,000 个文件。如果需要更多脚本文件,你可以使用数据存储。如果你在.py脚本中编辑了脚本文件以及一个.amltmp文件,这是由笔记本编辑器使用的临时文件:

图 8.15 – 临时文件上传至快照中

图 8.15 – 临时文件上传至快照中

为了避免创建不需要的文件快照,你可以在脚本旁边的文件夹中添加.gitignore.amlignore文件,并排除符合特定模式的文件。导航到greeter-job文件夹中的.amlignore文件,如果在创建文件夹时尚未添加该文件,如图 8.16所示:

图 8.16 – 添加文件以排除临时文件被添加到快照中

图 8.16 – 添加.amlignore文件以排除临时文件被添加到快照中

打开.amlignore文件,并在其中添加以下行,以排除所有具有.amltmp文件扩展名的文件以及你正在编辑的.amlignore文件:

*.amltmp
.amlignore

打开chapter08.ipynb笔记本,添加一个单元,并添加以下代码以重新提交脚本:

from azureml.widgets import RunDetails
run = exp.submit(script)
RunDetails(run).show()

你正在重新提交之前步骤中创建的ScriptRunConfig的现有实例。如果你再次重启expscript变量。

这次,你正在使用 AzureML SDK 提供的RunDetails小部件。这是一个Jupyter Notebook小部件,用于查看脚本执行的进度。这个小部件是异步的,会在运行完成前不断更新。

如果你想打印运行状态,包括日志文件的内容,可以使用以下代码片段:

run.get_details_with_logs()

一旦运行完成,导航到该运行的Snapshot标签页。你会注意到临时文件已经消失。

注意,这次运行的执行时间显著减少。导航到运行的日志。注意,这次日志中没有出现20_image_build_log.txt文件,如图 8.17所示:

图 8.17 – 更快的运行执行和缺失的 20_image_build_log.txt 文件

图 8.17 – 更快的运行执行和缺失的 20_image_build_log.txt 文件

这是用于执行脚本的环境的Docker镜像构建日志。这个过程非常耗时。这些镜像被构建并存储在与您的 AzureML 工作区一起部署的容器注册表中。由于你没有修改执行环境,AzureML 在后续的运行中重新使用了之前创建的镜像。在接下来的部分,你将更好地理解什么是环境以及如何修改它。

理解执行环境

在 AzureML 工作区的术语中,环境意味着执行脚本所需的软件要求列表。这些软件要求包括以下内容:

  • 你的代码需要安装的 Python 包

  • 可能需要的环境变量

  • 你可能需要的各种辅助软件,如 GPU 驱动程序或 Spark 引擎,以确保你的代码能够正常运行。

环境是管理版本化的实体,它们可以在不同的计算目标之间实现可重复、可审计和可移植的机器学习工作流。

AzureML 提供了一个 AzureML-Minimal 精选环境列表,包含仅用于启用运行跟踪所需的最小 Python 包,你在跟踪模型演变部分看到过。另一方面,AzureML-AutoML 环境是一个更大的精选环境,提供了运行 AutoML 实验所需的 Python 包。

重要提示

AzureML 服务正在不断更新,旧的环境已经被淘汰,取而代之的是更新的环境。即使在 AzureML Studio 的网页界面中看不到 AzureML-MinimalAzureML-AutoML 环境,它们仍然可以供你使用。如果遇到任何错误,请从本章的 GitHub 仓库下载最新的代码。

图 8.18中,你可以看到与简化版的 AzureML-Minimal 环境相比,AzureML-AutoML 环境提供了多少额外的软件包:

图 8.18 - AzureML-Minimal 和 AzureML-AutoML 环境之间的 Python 包差异 AzureML-AutoML 环境

图 8.18 - AzureML-Minimal 和 AzureML-AutoML 环境之间的 Python 包差异

图 8.18 显示了 AzureML-Minimal 环境 版本 46AzureML-AutoML 环境 版本 61Conda 环境定义。Conda 使用这个 YAML 文件来安装 Python 版本 3.6.2 和在 - pip: 标记下列出的 pip 依赖包。如你所见,所有 pip 包都定义了特定的版本,使用 ==x.x.x 的标记。这意味着每次使用该 YAML 文件时,都会安装相同的 Python 包,这有助于保持稳定的环境,从而确保实验的可重复性。

创建环境时安装软件包是一个耗时的过程。这时你在前一部分看到的 Docker 技术就派上用场了。Docker 是一个开源项目,旨在自动化将应用程序部署为便携式、自给自足的容器。这意味着,与你每次想要运行脚本时都创建一个新环境不同,你可以创建一个 Docker 容器镜像,也称为 Docker 镜像,在这个镜像中,所有的 Python 依赖都已经内嵌到镜像中。此后,你可以重复使用该镜像来启动容器并执行脚本。事实上,所有 AzureML 精选环境都可以作为 Docker 镜像,在 viennaglobal.azurecr.io 容器注册表中找到。

重要提示

尽管创建 Docker 镜像用于环境的配置是常见的做法,但并非总是必需的。如果你在本地计算机或 AzureML 计算实例上运行实验,你可以使用现有的 Conda 环境,而无需使用 Docker 镜像。如果你打算使用远程计算,例如 AzureML 计算集群,则需要使用 Docker 镜像,因为否则你无法确保所提供的机器会具备你的代码执行所需的所有软件组件。

为了更好地理解到目前为止你所阅读的内容,你将重新运行之前的 greeter.py 脚本,并使用 AzureML-Minimal 环境:

  1. 在你的笔记本中,添加一个新单元并加入以下代码:

    from azureml.core import Environment
    minimal_env =\
    Environment.get(ws, name="AzureML-Minimal")
    print(minimal_env.name, minimal_env.version)
    print(minimal_env.Python.conda_dependencies.serialize_to_string())
    

    这段代码检索了 AzureML-Minimal 环境,该环境在之前在笔记本中初始化的 ws 变量所引用的 AzureML 工作区中定义。然后,它打印环境的名称和版本,以及你在 图 8.18 中看到的 Conda 环境 YAML 定义。

  2. 添加一个新单元,并输入以下内容:

    from azureml.core import Experiment, ScriptRunConfig
    target = ws.compute_targets['cpu-sm-cluster']
    script = ScriptRunConfig(
        source_directory='greeter-job',
        script='greeter.py',
        environment argument in the ScriptRunConfig constructor.
    

查看运行执行的输出。如果你仔细观察,你将看到以下这一行:

Status: Downloaded newer image for viennaglobal.azurecr.io/azureml/azureml_<something>:latest

这一行是 azureml-logs55_azureml-execution-something.txt 文件的一部分。该行告知你它正在从 Microsoft 所拥有的 viennaglobal 容器注册表中拉取 Docker 镜像。与此相对,上一节中,在没有指定策划环境的运行中,镜像是从你自己的容器注册表中拉取的——即与你的 AzureML 工作区关联的容器注册表,如 图 8.19 所示:

图 8.19 – 从你自己的容器注册表中拉取的镜像在没有使用策划环境的情况下执行

图 8.19 – 在没有使用策划环境的情况下,从你自己的容器注册表中拉取的镜像

这个观察结果引出了下一个类型的 AzureML 支持的环境——系统管理环境——你将在下一节中进行探索。

定义系统管理环境

Conda 环境定义或简单的 pip requirements.txt 文件。在上一节中,你没有在 ScriptRunConfig 构造函数中定义 environment 参数,因此使用了默认的 Conda 环境定义文件来创建存储在与 AzureML 工作区关联的 Azure 容器注册表 中的系统管理环境。现在,让我们显式地创建一个系统管理环境来与代码一起使用:

  1. 导航到你 AzureML 工作区的 笔记本 部分以及 文件 树视图。

  2. 点击 greeter-job 文件夹的三个点以打开上下文菜单(或者直接右击文件夹名称),然后选择 greeter-banner-job,如下面的截图所示:

    图 8.20 – 将 greeter-job 文件夹复制为一个名为 greeter-banner-job 的新文件夹

  3. 打开新文件夹中的 greeter.py 文件,并将代码更改为以下内容:

    import argparse
    Banner method from the asciistuff open source Python package. This method is used in the last print. This will output a fancy os module, which allows you to read the environment variables using the os.environ.get() method. The code tries to read the environment variable named GREET_HEADER, and if it is not defined, the default value, Message:, is assigned to the greet_header variable, which is printed before the banner message.Important noteIf you try to execute the modified `greeter.py` in a terminal within your AzureML *compute instance*, it will fail because you don't have the `asciistuff` package installed. To install it in your compute instance, you can use the `pip install asciistuff` command.
    
  4. asciistuff 包是一个 pip 包,你需要在执行环境中安装它,以确保代码能够正常运行。为了定义这个代码依赖,你将创建一个 Conda 环境定义文件。在 chapter08 文件夹中,添加一个名为 greeter-banner-job.yml 的新文件,并在其中添加以下内容:

    name: banner-env
    dependencies:
    - python=3.6.2
    - pip:
      - asciistuff==1.2.1 
    

    这个 YAML 文件定义了一个新的 Conda 环境,名为 banner-env,该环境基于 Python 版本 3.6.2,并安装了 asciistuff1.2.1 版本的 pip 包。

  5. 若要基于你刚定义的 Conda 环境创建一个 AzureML 环境,你需要进入 chapter08.ipynb 笔记本,添加一个单元格,并输入以下代码:

    from azureml.core import Environment
    banner_env = Environment.from_conda_specification(
                     name = "banner-env",
                     file_path = "greeter-banner-job.yml")
    banner_env.environment_variables["GREET_HEADER"] = \
                                     "Env. var. header:"
    

    这段代码创建了一个名为 banner-env 的 AzureML 环境,使用了 Environment 类的 from_conda_specification() 方法。banner_env 变量包含了新定义的环境。在随后的代码行中,你定义了 GREET_HEADER 环境变量,并为其赋值为 Env. var. header:。该环境未在工作区中注册,使用时不需要注册。如果你确实想要将它保存到工作区,以便像引用策划环境一样引用它,并希望保持版本记录,可以使用 register() 方法,使用 banner_env.register(ws) 代码,其中你传入一个指向工作区的变量,该工作区将是该环境的注册位置。

    重要说明

    如果你计划先在本地计算机上工作,然后再扩展到更强大的计算集群上,你应考虑创建并注册一个系统管理的环境,包含你所需的所有 Python 包。这样,你可以在本地和远程执行时都重复使用它。

  6. 若要使用这个新定义的环境,请在笔记本中添加一个新单元格,并输入以下代码:

    script = ScriptRunConfig(
        source_directory='ScriptRunConfig::*   The source directory has changed to point to the `greeter-banner-job` folder, which contains the updated script.*   The environment argument is specified, passing your very own defined `banner_env` environment. 
    

该实验的输出应与 图 8.21 中所示相似:

图 8.21 – 从环境变量读取的头部文本和基于横幅的问候语

图 8.21 – 从环境变量读取的头部文本和基于横幅的问候语

正如你注意到的,在你刚刚创建的系统管理环境中,你没有指定任何关于基础操作系统的信息(例如,是否已在基础系统中安装了Conda)。你只是指定了已安装的Conda依赖项。如果你想要更大的灵活性,你可以显式配置环境并手动安装所有的软件要求。这些环境被称为用户管理环境。通常,这些用户管理环境是自定义的 Docker 镜像,封装了所有必需的依赖项。例如,你可能需要 PyTorch 框架的自定义构建,或者甚至是 Python 的自定义构建版本。在这些情况下,你需要负责安装 Python 包并配置整个环境。在本书中,你将使用经过精心策划或由系统管理的环境。

到目前为止,你已经探索了如何在远程计算机上执行一个简单的问候程序 Python 应用。在接下来的部分,你将继续训练你的diabetes模型,并了解如何在远程计算集群上训练该模型。

在计算集群上训练糖尿病模型

在前面的部分中,你了解了如何通过在笔记本中调用exp.submit(script)方法在远程计算集群上运行脚本,如图 8.22所示:

图 8.22 – 在计算集群上执行脚本

图 8.22 – 在计算集群上执行脚本

当你调用submit方法时,后台发生了以下操作:

  1. AzureML SDK 执行了一个 ScriptRunConfig

  2. AzureML 工作区检查是否已经存在Environment的 Docker 镜像。如果没有,它会在 Azure 容器注册表中创建。

  3. 任务被提交到计算集群,集群会扩展以分配一个计算节点。在新分配的计算节点中执行以下操作:

  4. 带有环境的 Docker 镜像被拉取到计算节点上。

  5. ScriptRunConfig引用的脚本被加载到正在运行的 Docker 实例中。

  6. 指标和元数据存储在 AzureML 工作区中。

  7. 输出将存储回存储帐户。

使用笔记本训练简单的 sklearn 模型部分中,你在 chapter08.ipynb 笔记本中创建了一个训练脚本。训练发生在 Jupyter 服务器的进程中,位于你的计算实例内部。要在计算集群上运行相同的训练,你需要执行以下操作:

  1. 将代码移动到 Python 脚本文件中。

  2. 创建一个 AzureML 环境来运行训练。

  3. 在实验中提交ScriptRunConfig

在接下来的部分中,你将看到如何将你在跟踪模型演变部分中使用的脚本转换,以便能够在远程计算集群上执行它。

将代码移动到 Python 脚本文件中

如果你查看你在跟踪模型演变部分创建的脚本,在进行训练的代码中,你使用了run变量来记录指标。这个变量引用了你在调用exp.start_logging()时获得的Run对象。在前一部分中,你了解了ScriptRunConfig,它在 Experiment 中提交并返回了一个Run类的实例。这个实例是在计算实例的笔记本中创建的。那么,如何让执行在远程集群上的脚本文件访问相同的Run对象呢?

AzureML 的Run类提供了一个叫做get_context()的方法,它返回当前服务执行上下文。对于ScriptRunConfig,这个执行上下文就是在调用exp.submit(script)时创建的相同Run对象:

from azureml.core.run import Run
run = Run.get_context()

除了run变量,在训练脚本中,你还使用了ws变量,它是指向 AzureML 工作区的引用。你使用该变量来访问diabetes数据集。你通过调用from_config方法来获取工作区的引用。这个方法的问题在于,当你第一次调用时,你需要手动进行身份验证并授权计算资源代表你访问工作区。这样的方法在远程计算环境中是不可行的。

run变量通过在 Experiment 属性中导航,再到该 Experiment 的工作区属性,为你提供了访问对应工作区的方式:

ws = run.experiment.workspace

然而,这些代码行有一个警告。你的代码假设 Python 脚本是通过ScriptRunConfig提交的。如果你在终端本地运行 Python 脚本,使用以下命令行,你将会遇到错误:

python training.py --alpha 0.1

get_context()方法将返回一个_OfflineRun类的对象,该类继承自Run类。这个类提供了你在实验中跟踪指标部分看到的所有日志功能,但它并不会将指标或工件上传到工作区,而是直接在终端中打印尝试结果。显然,这个run没有关联任何 Experiment,这会导致脚本抛出错误。因此,你需要使用你一直在使用的from_config()方法来检索工作区引用。由于终端是计算实例的一部分,脚本将在不提示身份验证的情况下执行,并且会传递你的凭据,正如你稍后在本节中看到的那样。如果你在本地计算机上运行这段代码,你将需要进行设备身份验证,正如你在第七章从设备进行身份验证部分中所看到的,AzureML Python SDK

允许你在终端离线运行并在计算集群中提交的完整代码如下:

from azureml.core import Workspace
from azureml.core.run import Run, _OfflineRun
run = Run.get_context()
ws = None
if type(run) == _OfflineRun:
    ws = Workspace.from_config()
else:
    ws = run.experiment.workspace

这些就是你需要对脚本做出的唯一修改,目的是为了提交到远程执行并利用 AzureML SDK 的功能。

重要提示

Python 开发者通常会在他们想标记为内部的类、属性或方法前加一个_前缀。这意味着标记的代码是供SDK库中的类使用,外部开发者不应该使用这些代码。标记的代码可能在未来发生变化而不会提前通知。通常不推荐使用以_开头的类,然而,_OfflineRun类在 AzureML SDK 的公共示例中被广泛使用,使用它是安全的。

让我们在工作区中进行这些更改。在文件树中,在chapter08下创建一个名为diabetes-training的文件夹,并在其中添加一个training.py文件,正如图 8.23所示:

图 8.23 – 为远程糖尿病模型训练创建训练脚本

图 8.23 – 为远程糖尿病模型训练创建训练脚本

training.py脚本中添加以下代码块。你可以直接从本章技术要求部分提到的 GitHub 仓库中下载这些代码,而不需要手动输入:

from sklearn.linear_model import LassoLars
from sklearn.metrics import mean_squared_error
from azureml.core import Workspace
from azureml.core.run import Run, _OfflineRun
import argparse
import os
import joblib

这些是脚本文件中所需的所有导入。将所有import语句放在脚本文件顶部是一种良好的编程习惯,这样可以方便地发现代码执行所需的模块。如果你使用flake8来检查代码,它会提醒你如果没有遵循这一最佳实践:

parser = argparse.ArgumentParser()
parser.add_argument('--alpha', type=float, 
                  dest='alpha', help='The alpha parameter')
args = parser.parse_args()

这个脚本文件需要传入--alpha参数。在这个代码块中,使用你在使用计算集群扩展训练过程部分看到的argparse模块解析这个参数,并将float类型的值赋给args.alpha变量,正如在dest参数中指定的那样。如果你传递了未定义的参数给脚本,parse_args方法将会抛出错误。有些人更喜欢使用args, unknown_args = parser.parse_known_args(),代替代码块的第四行,这样即使脚本收到比预期更多的参数,也能执行,并将未知参数赋值给unknown_args变量:

run = Run.get_context()
ws = None
if type(run) == _OfflineRun:
    ws = Workspace.from_config()
else:
    ws = run.experiment.workspace

在这个代码块中,你通过开头部分看到的代码片段获取到Run对象和Workspace的引用。一旦获得Workspace的引用,你就可以加载diabetes数据集,正如下一个脚本块所示:

diabetes_ds = ws.datasets['diabetes']
training_data, validation_data = \
               diabetes_ds.random_split(
                            percentage = 0.8, seed=1337)
X_train = training_data.drop_columns('target') \
                       .to_pandas_dataframe()
y_train = training_data.keep_columns('target') \
                       .to_pandas_dataframe()
X_validate = validation_data.drop_columns('target') \
                            .to_pandas_dataframe()
y_validate = validation_data.keep_columns('target') \
                            .to_pandas_dataframe()

在这个代码块中,您获得 diabetes 数据集的引用,并将其拆分为所需的 X_trainy_trainX_validatey_validate pandas 数据框,这些数据框您在本章的 在笔记本中训练简单的 sklearn 模型 部分中看到过。请注意,您在 random_split 方法中指定了 seed 参数。这个 seed 参数用于初始化 split 方法背后使用的随机函数的状态,以便从数据集中随机选择行。这样,每次调用该随机函数时,它都会生成相同的随机数。这意味着 training_datavalidation_data 每次运行脚本时都会保持一致。拥有相同的训练和验证数据集有助于正确比较在不同 alpha 参数下执行相同脚本的多次结果:

def train_and_evaluate(run, alpha, X_t, y_t, X_v, y_v):
  model = LassoLars(alpha=alpha)
  model.fit(X_t, y_t)
  predictions = model.predict(X_v)
  rmse = mean_squared_error(predictions,y_v,squared=False)
  range_y_validate = y_v.to_numpy().ptp()
  nrmse = rmse/range_y_validate
  run.log("nrmse", nrmse)
  run.log_row("nrmse over α", α=alpha, nrmse=nrmse)
  return model, nrmse

在此代码块中,您定义了 train_and_evaluate 方法,这与本章 追踪模型演变 部分中使用的方法相同:

model, nrmse = train_and_evaluate(run, args.alpha,
                  X_train, y_train, X_validate, y_validate)

在定义方法后,您调用训练过程并传递所有必需的参数:

os.makedirs('./outputs', exist_ok=True)
model_file_name = 'model.pkl'
joblib.dump(value=model, filename=
           os.path.join('./outputs/',model_file_name))

最后一个代码块将模型存储在 outputs 文件夹中,该文件夹位于脚本的同一位置。

您可以在本地计算实例上运行脚本,您会注意到模型按预期进行训练,指标会记录在终端中,如 图 8.24 所示。这是您之前阅读过的 _OfflineRun 类的预期行为:

图 8.24 – 在本地运行训练脚本

图 8.24 – 在本地运行训练脚本

到目前为止,您已经创建了训练脚本。在下一部分中,您将创建 AzureML 环境,该环境将包含执行该脚本所需的所有依赖项,以便在远程计算上运行。

创建用于运行训练脚本的 AzureML 环境

追踪模型演变部分中创建的训练脚本使用了 scikit-learn 库,也称为 sklearn。您在笔记本体验中使用的 Jupyter 内核已经安装了 sklearn 库。要查看当前在内核中安装的版本,请转到 chapter08.ipynb 笔记本,并在新的单元格中添加以下代码片段:

!pip show scikit-learn

该命令将使用 Python 的 pip 包管理器显示当前安装的 scikit-learn 包的详细信息,如 图 8.25 所示:

图 8.25 – 安装的 scikit-learn 库的包信息

图 8.25 – 安装的 scikit-learn 库的包信息

重要提示

如果您不确定库的名称,可以使用 pip freeze 命令来获取当前 Python 环境中已安装包的完整列表。

您还可以通过在 Python 脚本中使用 sklearn.__version__ 属性(注意两个下划线)来查找已安装库的版本。在新的笔记本单元格中,添加以下 Python 代码行:

import sklearn
print(sklearn.__version__)

你应该能够在输出中看到完全相同的版本。大多数 Python SDK 和库都有这个__version__属性,比如 PyTorch 和 TensorFlow 框架。

有两种方法可以安装scikit-learn包:作为Conda包或作为pip包。Conda提供了一个精选的 Python 包列表,并且这是推荐的方式。在理解执行环境部分,你看到了如何使用Conda规范文件创建环境。在本部分,你将学习一种不同的方法,在 Python 代码中创建环境。在chapter08.ipynb笔记本中添加一个新单元格,并输入以下内容:

from azureml.core import Environment
from azureml.core.conda_dependencies import CondaDependencies 
import sklearn
diabetes_env = Environment(name="diabetes-training-env")
diabetes_env.Python.conda_dependencies = CondaDependencies()
diabetes_env.Python.conda_dependencies.add_conda_package(
                   f"scikit-learn=={sklearn.__version__}")
diabetes_env.python.conda_dependencies.add_pip_package("azureml-dataprep[pandas]")

在前面的代码片段中,你创建了一个新的系统管理环境,然后使用add_conda_package添加了特定版本的scikit-learn。你还使用add_pip_package添加了azureml-dataprep[pandas]包,这是为了在training.py脚本中使用to_pandas_dataframe方法所必需的。你本可以像之前安装的asciistuff包一样,添加其他的 pip 包。你可以通过使用CondaDependencies类的create方法来一次性添加多个包,如下面的代码片段所示:

diabetes_env.Python.conda_dependencies = \
CondaDependencies.create(
      conda_packages=[
                   f"scikit-learn=={sklearn.__version__}"],
      pip_packages=["azureml-defaults", "azureml-dataprep[pandas]"])

你可以通过将包添加到conda_packagespip_packages数组中来要求环境中包含多个包。请注意,由于你没有将包附加到默认的CondaDependencies中,因此需要手动添加azureml-defaults包,以便training.py脚本能够访问azureml.core模块。

你可能会问,为什么我们没有在 Python 依赖项中定义joblibscikit-learn包依赖于joblib包,它会自动安装在环境中。如果你愿意,可以通过以下代码显式地在依赖项列表中指定它:

import joblib
diabetes_env.Python.conda_dependencies.add_pip_package(f"joblib=={joblib.__version__}")

重要说明

虽然不是强制要求指定你要添加到环境中的包的版本,但这是一个好的做法。如果你写了add_conda_package("scikit-learn"),没有指定包的版本,AzureML 会假定你指的是最新版本。当你第一次在 AzureML 中使用环境时,Docker 镜像会被创建,安装当时最新版本的scikit-learn包。那个版本可能比你用于创建脚本的版本更新,且可能与您编写的代码不兼容。虽然次要版本的差异可能不会影响你的代码,但主要版本的变化可能会引入破坏性更改,就像 TensorFlow 从版本 1升级到版本 2时所做的那样。

如果你不想创建一个包含代码依赖的全新环境,可以使用其中一个由 AzureML 精心策划的环境。你可以选择高度专业化的基于 GPU 的AzureML-Scikit-learn0.24-Cuda11-OpenMpi4.1.0-py36环境,或者使用更通用的AzureML-Tutorial策划环境,该环境包含了如scikit-learnMLflowmatplotlib等最常用的数据科学库。

到目前为止,你已经编写了训练脚本并定义了包含所需sklearn库的 AzureML 环境。在下一节中,你将启动计算集群上的训练。

在 Experiment 中提交ScriptRunConfig

一旦你有了脚本和 AzureML 环境定义,你就可以提交ScriptRunConfig以在远程计算集群上执行。在chapter08.ipynb笔记本的新单元中,添加以下代码:

from azureml.core import Workspace, Experiment
from azureml.core import ScriptRunConfig
ws = Workspace.from_config()
target = ws.compute_targets['cpu-sm-cluster']
script = ScriptRunConfig(
    source_directory='diabetes-training',
    script='training.py',
    environment=diabetes_env,
    compute_target=target,
    arguments=['--alpha', 0.01]
)
exp = Experiment(ws, 'chapter08-diabetes')
run = exp.submit(script)
run.wait_for_completion(show_output=True)

这段代码与之前章节中提交greeter.py脚本的代码相同。你获得了对 AzureML 工作区和你将要执行作业的计算集群的引用。你定义了一个ScriptRunConfig对象,在其中定义了要执行的脚本位置、你在前一节中定义的环境和目标计算资源。你还将alpha参数传递给了脚本。在代码的最后一部分,你创建了一个 Experiment 并提交了ScriptRunConfig以执行。

通过这段代码,你触发了本章中第 8.22 图的流程,该流程出现在在计算集群上训练糖尿病模型一节中。

一旦训练完成,你就可以进入 Experiment,选择运行任务,并查看从训练过程中收集的指标,如第 8.26 图所示:

图 8.26 – 来自远程计算集群上运行脚本的记录指标

图 8.26 – 来自远程计算集群上运行脚本的记录指标

到目前为止,你已经成功地在远程计算集群的单个节点上执行了diabetes模型训练脚本,并且已经在 AzureML Experiment 的运行记录中记录了指标和训练后的模型。

在下一节中,你将发现不同的方式来扩展你的计算工作,并充分利用计算集群中不止一个节点。

在模型训练过程中利用多个计算节点

正如你在第四章配置工作区部分看到的那样,集群可以从 0 个计算节点扩展到你需要的任意数量。你需要在模型训练阶段使用多个节点而不仅仅是一个节点的原因有几个,具体如下:

  • 不相关的模型训练实例的并行执行:当你在团队中工作时,通常会有多个 Experiment 并行运行。每个作业可以在单个节点上运行,就像你在前一节中所做的那样。

  • 单一模型的并行训练,也称为分布式训练:这是一个高级场景,您正在使用如Apache Horovod的分布式深度学习训练框架,该框架被 PyTorch 和 TensorFlow 所使用。分布式训练有两种类型:

    • 数据并行性:将训练数据分割成与计算节点数量相等的分区。每个节点对分配的数据执行一批模型训练,然后所有节点在进入下一批之前同步更新的模型参数。

    • 模型并行性:在不同的计算节点上训练模型的不同部分。每个节点只负责训练整个模型的一小段,并且在每次需要传播步骤时,节点之间会进行同步。

  • 您在前一节中训练的LassoLars模型的alpha参数。您可能希望探索这些参数的多个值,以选择在训练数据集上表现最好的模型。这是一个称为超参数调优的过程,您将在第九章中了解更多关于它的内容,优化 ML 模型

  • 并行训练多个模型以选择最佳备选方案:这是您在第五章中已经发现的 AutoML 过程,让机器做模型训练。您还将在第九章中再次看到这种方法,优化 ML 模型,在使用代码运行 AutoML 实验部分。

在本节中,您学习了利用计算集群中多个节点的不同方法。您将在第九章中深入探讨最后两种方法,优化 ML 模型

总结

在本章中,您概览了在 AzureML 工作区中创建 ML 模型的各种方式。您从一个简单的回归模型开始,该模型在 Jupyter notebook 的内核进程中进行训练。您学习了如何跟踪您训练的模型的指标。然后,您将训练过程扩展到在第七章中创建的cpu-sm-cluster计算集群中,AzureML Python SDK。在扩展到远程计算集群时,您了解了 AzureML 环境是什么,以及如何通过查看日志来排除远程执行的问题。

在下一章中,您将基于这些知识,使用多个计算节点执行并行的超参数调优过程,从而找到适合您模型的最佳参数。您还将学习如何使用 AzureML SDK 的 AutoML 功能,完全自动化模型选择、训练和调优。

问题

在每一章中,您会发现几个问题来检查您对讨论主题的理解:

  1. 你想记录你将在脚本中使用的验证行数。你将使用Run类中的哪个方法?

    a. log_table

    b. log_row

    c. log

  2. 你想运行一个使用scikit-learn的 Python 脚本。你将如何配置 AzureML 环境?

    a. 添加 scikit-learn Conda 依赖项。

    b. 添加 sklearn Conda 依赖项。

    使用 AzureML 的Azure-Minimal环境,该环境已经包含所需的依赖项。

  3. 你需要使用 MLflow 跟踪实验中生成的指标,并将其存储在你的 AzureML 工作区中。你需要在 Conda 环境中安装哪两个 pip 包?

    a. mlflow

    b. azureml-mlflow

    c. sklearn

    d. logger

  4. 你需要使用 MLflow 来跟踪 training_rate 指标的值 0.1。以下哪段代码可以实现此要求?假设所有类已在脚本顶部正确导入:

    a. mlflow.log_metric('training_rate', 0.1)

    b. run.log('training_rate', 0.1)

    c. logger.log('training_rate', 0.1)

深入阅读

本节提供了一些网络资源列表,帮助你扩展对 AzureML SDK 和本章中使用的各种代码片段的知识:

第九章:第九章:优化机器学习模型

在本章中,你将学习两种可以帮助你发现数据集最佳模型的技术。你将首先探索HyperDrive包,这是 AzureML SDK 的一部分。这个包允许你通过调整其暴露的参数来优化模型的性能,这个过程也被称为超参数调优。接下来,你将探索自动化机器学习AutoML)包,这是 AzureML SDK 的一部分,它允许你通过代码自动化模型选择、训练和优化过程。

在本章中,我们将涵盖以下主要内容:

  • 使用 HyperDrive 进行超参数调优

  • 使用代码运行 AutoML 实验

技术要求

你需要有 Azure 订阅权限。在该订阅中,你需要有一个名为packt-azureml-rg的资源组。你还需要拥有ContributorOwner权限的packt-learning-mlw,如第二章《部署 Azure 机器学习工作区资源》中所述。

你还需要对Python语言有基本的了解。本章中的代码片段适用于 Python 3.6 或更高版本。你还应当熟悉在 AzureML Studio 中的 Notebook 体验,这在第八章《使用 Python 代码实验》中有讲解。

本章假设你已经在 AzureML 工作区中注册了scikit-learn糖尿病数据集,并且已经创建了一个名为cpu-sm-cluster的计算集群,具体内容请参见第七章《AzureML Python SDK》中的定义数据存储处理数据集处理计算目标部分。

你可以在 GitHub 的bit.ly/dp100-ch09网址找到本章的所有笔记本和代码片段。

超参数调优使用 HyperDrive

第八章《使用 Python 代码实验》中,你训练了一个LassoLars模型,该模型接受alpha参数。为了避免过拟合训练数据集,LassoLars模型使用了一种技术,alpha参数指定了惩罚项的重要性,这直接影响训练结果。影响训练过程的参数被称为DecisionTreeClassifier类,该类位于scikit-learn库中。你可以通过max_depth来定义树的最大深度,max_depth是一个整数。在同一个模型中,你还可以通过为max_leaf_nodes超参数指定一个数值来控制叶节点的最大数量。

这些超参数控制决策树的大小,如图 9.1所示:

![图 9.1 – 决策树超参数]

](https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/az-ds-ass-cert-gd/img/B16777_09_001.jpg)

图 9.1 – 决策树超参数

超参数调整是找到产生最佳性能模型的超参数的最佳值的过程,用于对训练数据进行评估。要评估每个超参数组合的性能,必须训练模型并评估性能度量。在糖尿病模型的情况下,在第八章中,使用 Python 代码进行实验,您使用标准化根均方误差NRMSE)度量评估模型。

AzureML SDK 提供了HyperDriveConfig类,允许您执行HyperDriveConfig是您在第八章中使用的ScriptRunConfig类的包装器,使用 Python 代码进行实验。这意味着您需要在run_config参数中传递您要用于训练模型的ScriptRunConfig。您还需要指定代码正在记录的度量标准以及该度量标准的目标。在糖尿病案例中,您试图最小化在第八章中看到的submit方法,使用 Python 代码进行实验。显示端到端过程的伪代码,其中script变量是定义要使用的训练脚本的ScriptRunConfig对象,如下所示:

hd_config = HyperDriveConfig(
             run_config=script,
             primary_metric_name="nrmse",
             primary_metric_goal=PrimaryMetricGoal.MINIMIZE
             ,…)
experiment = Experiment(ws, "chapter09-hyperdrive")
hyperdrive_run = experiment.submit(hd_config)

除了ScriptRunConfig,您还需要传递HyperDriveConfig将使用。超参数可以接受离散或连续值:

  • 典型的离散值示例是整数或字符串值。例如,在activation中,selu用于relu修正线性单元ReLU)。

  • 典型的连续值示例是浮点数值。您一直在训练的LassoLars模型中的alpha参数是接受浮点值的超参数

当您探索可能的azureml.train.hyperdrive.parameter_expressions模块时。

在离散choice函数的情况下,您可以使用以下脚本指定activation 超参数的选项列表,这是您之前看到的典型示例:

choice('selu','relu')

此脚本将尝试使用selurelu激活函数来寻找最佳模型。

重要提示

如果您对神经网络工作感兴趣,可能需要更好地理解这些激活函数。有一些很棒的书籍可以帮助您开始神经网络设计。对于 DP-100 考试,您不需要这些知识。

注意,即使在连续的alpha LassoLars模型的情况下,您仍然可以使用choice方法来定义要探索的离散值。例如,以下choice的使用等同于您在第八章跟踪模型演变部分所做的:

choice(0.001, 0.01, 0.1, 0.25, 0.5)

您还可以定义在探索搜索空间时将获得的样本的概率分布。例如,如果您想为所有值提供相等的机会,您将使用均匀分布。另一方面,您可以使用正态分布将搜索区域集中在搜索空间的中心。AzureML SDK 提供了一些方法,您可以使用它们,如uniform(low, high)loguniform(low, high)normal(μ, σ)lognormal(μ, σ)。对于离散值,您可以使用以q为前缀的等效方法,如quniform(low, high, q)qloguniform(low, high, q)qnormal(μ, σ, q)qlognormal(μ, σ, q),其中q参数是量化因子,用于将连续值转换为离散值。

在本书的 GitHub 页面上,您可以找到用于绘制生成 1,000 个样本并使用这些函数分布的代码。结果可以在图 9.2中看到:

图 9.2 – 高级离散和连续超参数值分布。样本值已排序。x 轴显示排序值的索引号

](https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/az-ds-ass-cert-gd/img/B16777_09_002.jpg)

图 9.2 – 高级离散和连续超参数值分布。样本值已排序。x 轴显示排序值的索引号

重要提示

图 9.2中,在loguniformlognormal的图表中,量化因子为 1 的离散函数的线与连续函数的线重合。因此,您只能看到两条线。

定义了搜索空间之后,您需要指定将用于选择每个azureml.train.hyperdrive模块的采样策略:

  • 您在上面看到的choice方法。Azure ML SDK 将搜索这些离散值的所有可能超参数组合。假设您希望探索以下四种参数组合:

    • a=0.01,b=10

    • a=0.01,b=100

    • a=0.5,b=10

    • a=0.5,b=100

    以下代码片段定义了这四种组合的搜索空间:

    from azureml.train.hyperdrive import GridParameterSampling
    from azureml.train.hyperdrive import choice
    param_sampling = GridParameterSampling( {
            "a": choice(0.01, 0.5),
            "b": choice(10, 100)
        }
    )
    
  • RandomParameterSampling类。它允许您从可用选项中随机选择超参数值。它支持离散和连续的超参数

  • max_total_runs您将会在后面了解。它支持离散和连续的超参数

让我们把到目前为止学到的所有知识付诸实践:

  1. 转到 AzureML Studio 网页界面的作者|笔记本部分。

  2. 创建一个名为chapter09的文件夹。

  3. 您需要在training.py脚本中创建一个名为diabetes-training的文件夹。该脚本与第八章中《使用 Python 代码实验》一节中将代码移至 Python 脚本文件部分使用的脚本相同。您可以从那里复制内容。最终的文件结构图见图 9.3

  4. chapter09 文件夹中创建一个名为 chapter09.ipynb 的笔记本。图 9.3 显示了最终 文件 树的结构:图 9.3 – 包含代码和 chapter09 笔记本的文件树结构

    图 9.3 – 包含代码和 chapter09 笔记本的文件树结构

  5. 在第一个单元格中添加以下初始化代码:

    from azureml.core import (
        Workspace, Environment
    )
    from azureml.core.conda_dependencies import \
         CondaDependencies 
    import sklearn
    ws = Workspace.from_config()
    diabetes_env = Environment(name=»diabetes-training-env»)
    diabetes_env.python.conda_dependencies = \
         CondaDependencies.create(
          conda_packages=[
              f"scikit-learn=={sklearn.__version__}"],
          pip_packages=["azureml-defaults",
                        "azureml-dataprep[pandas]"])
    target = ws.compute_targets['cpu-sm-cluster'] 
    

    这段代码与你在《第八章》 使用 Python 代码进行实验 部分中使用的代码类似。唯一的区别是你使用了 create 方法,而不是逐个添加包。

  6. 在新单元格中,定义将执行 training.py 脚本的 ScriptRunConfig 对象:

    from azureml.core import ScriptRunConfig
    script = ScriptRunConfig(
        source_directory='diabetes-training',
        script='training.py',
        environment=diabetes_env,
        compute_target=target
    )
    

    这个 ScriptRunConfig 对象与你在《第八章》 使用 Python 代码进行实验 部分中创建的几乎相同。唯一的区别是你没有传递 arguments 参数,特别是你没有指定 --alpha 参数。这个参数将由你在下一步配置的 HyperDriveConfig 对象自动附加。

  7. 在一个新单元格中添加并执行以下代码:

    from azureml.train.hyperdrive import HyperDriveConfig
    from azureml.train.hyperdrive import (
       RandomParameterSampling, uniform, PrimaryMetricGoal
    )
    param_sampling = RandomParameterSampling({
            'alpha': uniform(0.00001, 0.1),
        }
    )
    hd_config = HyperDriveConfig(
                   run_config=script,                          
                   hyperparameter_sampling=param_sampling,
                   primary_metric_name="nrmse", 
                   primary_metric_goal=                   
                              PrimaryMetricGoal.MINIMIZE,
                   max_total_runs=20,
                   max_concurrent_runs=4)
    

    在这段代码中,你定义了一个 RandomParameterSampling 方法,用来探索均匀分布的值,范围从 0.00001 到 0.1,用于传递给你在 第 3 步 中创建的训练脚本的 alpha 参数。这个训练脚本接受 --alpha 参数,随后该参数传递给 alpha LassoLars 模型。

    将此 RandomParameterSampling 配置分配给 HyperDriveConfighyperparameter_sampling 参数。

    你还已配置 HyperDriveConfigrun_config 属性,以使用你在第 6 步中定义的 ScriptRunConfig 对象。注意,RandomParameterSampling 类将传递脚本所需的 alpha 参数。

    然后,定义使用 primary_metric_name 参数评估生成的模型。你还指定了要最小化该值(primary_metric_goal 参数),因为它是你希望最小化的误差。

    最后的两个参数,max_total_runsmax_concurrent_runs,控制你愿意投入到寻找最佳模型的资源。max_total_runs 参数控制实验的最大运行次数,可以在 1 到 1,000 次之间。这是一个必填参数。max_concurrent_runs 是一个可选参数,控制并发运行的最大次数。在这种情况下,你定义了 4,这意味着在 ScriptRunConfig 中将仅配置四个节点。这意味着集群仍然会有一个未配置的节点,因为它能扩展到的最大节点数是五个,正如你在第七章 与计算目标的工作部分中定义的那样,AzureML Python SDK。还有一个可选参数可以用来限制搜索最佳模型的时间,max_duration_minutes 参数,你在上面的示例中没有指定,它定义了执行 超参数调优 过程的最大时长(分钟)。超过该时长后,所有后续调度的运行将自动取消。

  8. 在一个新单元格中,添加以下代码:

    from azureml.core import Experiment
    experiment = Experiment(ws, "chapter09-hyperdrive")
    hyperdrive_run = experiment.submit(hd_config)
    hyperdrive_run.wait_for_completion(show_output=True)
    

    在此代码中,你提交 HyperDriveConfig 以在 hyperdrive_run 变量下执行,该变量是 HyperDriveRun 的实例,继承自正常的 Run 类。

  9. 你可以在 Studio Web UI 中查看该过程的结果。导航到 alpha 超参数。你可以通过视觉化探索 alpha 参数的不同值对 HyperDriveRun (Run 1) 的 alpha 值的影响。

    重要提示

    在你的执行中,运行编号可能不同。每次你执行单元格时,都会创建一个新的运行编号,接着上一个编号。因此,如果你执行一个包含 20 个子运行的超参数调优运行,那么最后一个子运行将是第 21 号运行。下次执行相同代码时,超参数调优运行将从第 22 号开始,最后一个子运行将是第 42 号。此节中提到的运行编号是各个图示中显示的编号,观察到差异是正常的,尤其是在你需要重新运行某些单元格时。

  10. 导航到已完成的 Run 1 运行的 输出 + 日志 标签。你会注意到,在 azureml-logs 文件夹下有一个名为 hyperdrive.txt 的文件,如 图 9.5 所示:图 9.5 – HyperDriveRun 中的日志文件,选取将并行执行的超参数空间中的前四个作业    将并行执行的超参数空间

    图 9.5 – HyperDriveRun 中的日志文件,选取将并行执行的超参数空间中的前四个作业

    该文件包含所有为完成超参数调优过程而计划的作业。实际的运行日志和存储的模型都保存在子运行中。如果你需要调试代码问题,你需要打开其中一个子运行查看脚本错误。

  11. 你还可以获取最佳模型的运行情况,并且相应的 get_best_run_by_primary_metric 方法可以检索 hyperdrive_run 变量所引用的 HyperDriveRun 的最佳运行结果。从那里,你可以读取 Run 对象的 get_metrics 方法,进而使用 get_details 方法获取执行详情。在这些详情中,有一个 runDefinition 对象,它包含一个 arguments 列表,如 图 9.6 所示:

![图 9.6 – 揭开最佳运行.get_details()['runDefinition']['arguments'] 代码的神秘面纱

](https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/az-ds-ass-cert-gd/img/B16777_09_006.jpg)

图 9.6 – 揭开最佳运行.get_details()['runDefinition']['arguments'] 代码的神秘面纱

在这一节中,你看到了如何运行 超参数调优 过程来找到模型 超参数 的最佳值。在下一节中,你将看到如何通过使用提前终止策略来优化寻找最佳值的时间。

使用提前终止策略

HyperDriveConfig 构造函数的参数之一是 policy。该参数接受一个 EarlyTerminationPolicy 对象,定义了可以提前终止运行的策略。默认情况下,这个参数的值为 None,意味着会使用 NoTerminationPolicy 类,允许每次运行执行直到完成。

要能够使用提前终止策略,你的脚本必须在每次运行中执行多个迭代。

Files 视图中,添加一个名为 termination-policy-training 的文件夹,并在其中添加一个 training.py 文件,如 图 9.7 所示:

图 9.7 – 添加一个执行多个纪元的训练脚本

图 9.7 – 添加一个执行多个纪元的训练脚本

在训练脚本中添加以下代码:

from azureml.core.run import Run
import argparse
import time
parser = argparse.ArgumentParser()
parser.add_argument("--a", type=int, dest="a", help="The alpha parameter")
parser.add_argument("--b", type=int, dest="b", help="The beta parameter")
args = parser.parse_args()
if (args.a > 2):
    args.a = 0
run = Run.get_context()
def fake_train(run, a, b):
    time.sleep(5)
    metric = a + b
    run.log("fake_metric", metric)
for epoch in range(20):
    fake_train(run, args.a * epoch, args.b)

该脚本获取两个参数,ab,然后调用 fake_train 方法 20 次。在数据科学文献中,人们将这 20 次称为 20 个 纪元,它们是整个训练数据集上的训练周期。

在每个纪元中,a 参数会乘以迭代次数,该次数是从 0 一直到 19 的整数值,然后调用 fake_train 方法。fake_train 方法会暂停 5 秒钟以模拟训练过程,然后将修改后的 a 值加到 b 参数上。结果会记录在 fake_metric 指标中。

此外,在 第 8 行,代码检查传递给脚本的 a 参数。如果它大于 2,它会变为 0。这意味着你正在训练的虚拟模型在 a 值增加到 2 时表现更好,然后它的性能会下降,如 图 9.8 所示。

请注意,你不需要读取任何数据集,因此不需要引用Workspace。这就是为什么上面代码中的第 10 行不需要检查它是否是_OfflineRun对象,就像你在第八章中的将代码移到 Python 脚本文件部分所做的那样,使用 Python 代码进行实验

如果你运行HyperDriveConfig,并在所有从14之间的值上进行网格搜索,观察fake_metric在每个时期的演化。在图的右侧,你可以看到fake_metric是如何受到不同ab值的影响的,a表现得比使用a参数34训练的模型更好,关于fake_metric

图 9.8 – 没有早期终止策略的超参数调优

](https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/az-ds-ass-cert-gd/img/B16777_09_008.jpg)

图 9.8 – 没有早期终止策略的超参数调优

理想情况下,你希望减少等待所有运行完成的时间。EarlyTerminationPolicy 允许你监控正在运行的任务,如果它们的表现比其他任务差,则提前取消它们。最终的输出将像图 9.9中所示,你可以看到有些任务在到达第二十个报告的间隔之前就被终止了(图表从 0 开始计数),节省了时间和计算资源:

图 9.9 – 使用激进的早期终止策略进行超参数调优

](https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/az-ds-ass-cert-gd/img/B16777_09_009.jpg)

图 9.9 – 使用激进的早期终止策略进行超参数调优

AzureML SDK 提供了一些内置的EarlyTerminationPolicy实现,位于azureml.train.hyperdrive模块中:

  • NoTerminationPolicy:这是默认的停止策略,允许所有运行完成。

  • MedianStoppingPolicy:中位数停止策略计算所有运行的运行平均值。然后,它会取消那些最佳表现差于运行平均值中位数的运行。你可以将此策略看作是将每次运行的表现与前面运行的平均表现进行比较。这个策略的优点在于它考虑了到目前为止所有的运行,而不仅仅是将当前的运行与迄今为止最好的运行进行比较。这一特点使得中位数停止策略能够避免陷入局部最优值。

  • BanditPolicy:Bandit 策略计算当前运行和表现最佳的运行之间的距离,然后根据某些容差标准终止当前运行。你可以定义绝对距离(slack_amount参数)或与表现最佳的运行的最大允许比率(slack_factor参数)。

  • TruncationSelectionPolicy:截断选择策略是最激进的策略,它取消某个百分比(由 truncation_percentage 参数定义)的运行,这些运行在主要指标上的表现排在最后。当对一个相对较新的运行进行排名时,在早期的迭代中,该策略会将其与较老运行在同一迭代的表现进行比较。因此,这个策略力图通过考虑随着训练时间推移模型表现的提升来实现排名的公平性。

所有策略都接受两个可选参数:

  • evaluation_interval:应用策略的频率。

  • delay_evaluation:这将延迟第一次策略评估,直到指定的间隔次数,给予年轻运行足够的时间以达到成熟状态。

让我们使用最推荐的策略 MedianStoppingPolicy,对你上面创建的脚本进行超参数调整:

  1. 转到将在超参数调整过程中使用的 ScriptRunConfig 对象。

  2. 在一个新单元格中,添加以下代码:

    from azureml.train.hyperdrive import (
        GridParameterSampling,    
        choice,
        MedianStoppingPolicy,
        HyperDriveConfig,
        PrimaryMetricGoal
    )
    param_sampling = GridParameterSampling(
        {
            "a": choice(1, 2, 3, 4),
            "b": choice(1, 2, 3, 4),
        }
    )
    early_termination_policy = MedianStoppingPolicy(
        evaluation_interval=1, delay_evaluation=5
    )
    hd_config = HyperDriveConfig(
        policy=early_termination_policy,
        run_config=script,
        hyperparameter_sampling=param_sampling,
        primary_metric_name="fake_metric",
        primary_metric_goal=PrimaryMetricGoal.MAXIMIZE,
        max_total_runs=50,
        max_concurrent_runs=4
    )
    

    这个 HyperDriveConfig 对象使用 MedianStoppingPolicy 作为其策略参数,在第一次 5 次迭代后评估所有运行,并在每次迭代中将它们的结果与当前的运行平均值的中位数进行比较。

  3. 在一个新单元格中,添加以下代码以开始执行你在 步骤 2 中定义的 HyperDriveConfig 对象:

    experiment = Experiment(ws, "chapter09-hyperdrive")
    hyperdrive_run = experiment.submit(hd_config)
    hyperdrive_run.wait_for_completion(show_output=True)
    

    图 9.10 显示了此 HyperDriveRun 运行的结果,其中 16 个作业中只有 8 个提前终止:

图 9.10 – 使用中位数停止早期终止策略的超参数调整

图 9.10 – 使用中位数停止早期终止策略的超参数调整

重要提示

在上面的代码中,max_total_runs 参数的值为 50。这是潜在的子运行次数的上限。在这个示例中,你只有 16 种组合。这意味着实验将只运行 16 次,然后停止,因为整个搜索区域已经被搜索完毕。如果你希望 max_total_runs 参数生效,应指定一个小于 16 的值。

到目前为止,你已经看到了如何针对你拥有的数据优化特定的模型。在下一部分,你将看到如何通过 SDK 搜索最佳模型来运行 AutoML 实验,类似于你在第五章中所做的,让机器进行模型训练,通过 Studio 用户界面进行的操作。

使用代码运行 AutoML 实验

到目前为止,在本章中,你一直在微调一个 LassoLars 模型,执行超参数调整过程,以根据训练数据识别 alpha 参数的最佳值。在这一部分,你将使用 AutoML 和 AzureML SDK,自动选择最佳的数据预处理、模型和超参数设置,来匹配你的训练数据集。

要配置一个 AutoMLConfig 对象,你需要定义 任务类型指标训练数据计算预算。该过程的输出是一个模型列表,你可以从中选择最佳的运行和与该运行相关的最佳模型,如图 9.11所示:

图 9.11 – AutoML 过程

图 9.11 – AutoML 过程

根据你要建模的问题类型,你必须选择 task 参数,选择 classificationregressionforecasting,如图 9.12所示:

图 9.12 – AutoML 任务类型、算法和支持的指标

图 9.12 – AutoML 任务类型、算法和支持的指标

图 9.12 显示了 AzureML SDK 支持的部分算法。azureml.train.automl.constants.SupportedModels 包含 classificationregressionforecasting 类,这些类列出了所有作为属性的支持算法。由于预测只是回归的一个更专门化的版本,因此回归的所有算法都可以使用。AutoML 支持一些额外的、更专门的预测算法,例如非常流行的 ARIMA 技术或 Facebook 的 Prophet 算法。

primary_metric 参数决定了模型训练过程中用于优化的指标。回归和预测的指标相同。分类算法使用不同的指标,如图 9.12所示。

训练数据可以通过 training_data 参数提供,可以是 pandas Dataset 对象的格式。训练数据是表格格式,并包括 target 列。你定义你希望预测的列名,传递 label_column_name 参数。默认情况下,AutoML 会使用该数据集进行训练和验证。如果数据集超过 20,000 行,则会进行数据集拆分,保留 10% 用于验证。如果数据集小于 20,000 行,则使用交叉验证。如果你想指定从 training_data 创建多少个折叠,你可以使用 n_cross_validations 参数。另一种方法是提供 validation_size 参数,指定从训练数据中保留并用作验证的百分比(值为 0.01.0)。如果你想手动将数据分割为训练数据和验证数据,你可以将验证数据分配给 validation_data 参数,如本节后面所述。

计算预算 是你愿意为找到最佳机器学习模型而投入的金钱。它由三部分组成:

  • 计算集群的节点类型:计算集群的类型具有的能力越多,运行 AutoML 作业时每秒的成本就越高。这是你在创建计算集群时配置的设置,除非你创建一个新集群,否则在此时无法更改。

  • max_concurrent_iterations参数允许使用最多计算集群中的节点数。这将允许你运行并行迭代,但会增加成本。默认情况下,这个参数是1,意味着一次只允许进行一个迭代。

  • experiment_timeout_hours参数,或者你可以定义experiment_exit_score参数,定义达到某个分数后停止进一步探索。限制计算支出的另一种方法是限制要探索的不同算法和参数组合的数量。默认情况下,AutoML 会探索 1,000 种组合,你可以通过指定iterations参数来限制这个数量。

现在你已经探索了所有需要在AutoMLConfig对象中配置的选项,导航到你的chapter09.ipynb笔记本,添加一个新的单元格,并输入以下代码:

from azureml.core import Workspace, Dataset
from azureml.train.automl import AutoMLConfig
ws = Workspace.from_config()
compute_target = ws.compute_targets["cpu-sm-cluster"]
diabetes_dataset = Dataset.get_by_name(workspace=ws, name='diabetes')
train_ds,validate_ds = diabetes_dataset.random_split(percentage=0.8, seed=1337)
experiment_config = AutoMLConfig(
    task = "regression",
    primary_metric = 'normalized_root_mean_squared_error',
    training_data = train_ds,
    label_column_name = "target",
    validation_data = validate_ds,
    compute_target = compute_target,
    experiment_timeout_hours = 0.25,
    iterations = 4
)

在这段代码中,你获取了工作空间、计算集群的引用以及diabetes数据集,你将其分为训练集和验证集。然后你创建了一个AutoMLConfig对象,用于处理target列。你还指定了validation_data参数。

重要提示

如果不想分割数据集,你可以将整个数据集传递给training_data参数,并跳过validation_data参数。由于数据集仅包含 442 行,AutoML 会将训练数据集分为 10 个折叠,用于执行交叉验证技术。

然后,你定义了用于此训练的compute_target实验,并通过允许实验运行一个小时四分之一(experiment_timeout_hours参数),即 15 分钟,并仅探索 4 种模型和参数组合(iterations参数),来确定你的计算预算。在你的案例中,iterations参数可能会是终止AutoML实验的原因。

重要提示

对于预测,你需要指定forecasting_parameters,除了你之前定义的回归参数外。ForecastingParameters类包含以下常用参数:

  1. time_column_name:表示时间序列时间维度的列。

  2. max_horizon:所需的预测时间范围,以时间序列的频率为单位。默认值为1,这意味着你的模型将能够预测未来的一个时间点。这个时间点是你的数据集所使用的频率。如果你的数据集每小时有 1 行,并且你想预测 7 天的时间范围,则max_horizon需要设置为 7 天×24 个时间点/天=168。

到目前为止,您已经创建了experiment_config,它包含了您即将执行的AutoML实验的配置。添加一个新单元格,并输入以下代码来启动 AutoML 训练过程:

from azureml.core.experiment import Experiment
my_experiment = Experiment(ws, 'chapter09-automl-experiment')
run = my_experiment.submit(experiment_config, 
                           show_output=True)

run变量包含对通过submit方法创建的AutoMLRun对象的引用。几分钟后,过程将完成。要获取当前最佳的运行和最佳模型,您可以使用get_output()方法,如以下代码片段所示:

best_run, best_model = run.get_output()

或者,您也可以直接通过相应的Tuple索引访问最佳运行和最佳模型,如以下代码片段所示:

best_run = run.get_output()[0]
best_model = run.get_output()[1]

在每个自动化机器学习实验中,您的数据会自动进行缩放或归一化,以帮助算法表现得更好。这一数据转换将成为训练模型的一部分。这意味着您的数据首先通过数据转换器,然后模型将使用新的特征名称进行训练,这些特征名称对您不可见。您将在第十章《理解模型结果》中看到sklearn.composeColumnTransformer的示例。要查看嵌入在 AutoML 模型中的实际步骤,您可以使用生成的模型的steps属性:

best_model.steps

第一步名为datatransformer,包含了用于我们的diabetes数据集的插补器。无论是回归任务还是分类任务,这一步骤都被命名为datatransformer。对于预测任务,这一步骤命名为timeseriestransformer,并包含了额外的基于日期的转换。要获取转换列表和工程特征的名称,您可以使用以下代码片段:

print(best_model.named_steps['datatransformer'] \
                 .get_featurization_summary())
feature_names=best_model.named_steps['datatransformer'] \
                 .get_engineered_feature_names()
print("Engineered feature names:")
print(feature_names)

在本节中,您通过AutoML寻找了针对糖尿病回归问题的最佳模型。这也总结了您可以根据特定数据集优化机器学习模型的最常用方法。

总结

在本章中,您探讨了优化特定模型以在数据集上表现良好的最常用方法,以及如何自动化模型选择过程。您首先通过执行并行化的HyperDriveConfig类来优化LassoLars模型的alpha参数,您正在该参数下训练diabetes数据集。接着,您自动化了模型选择,使用 AutoML 来检测最佳的算法和参数组合,从而预测diabetes数据集的target列。

在下一章中,您将以此为基础,学习如何使用 AzureML SDK 来解释模型结果。

问题

  1. 您想通过model = run.get_output()[0]获取最佳模型。

    b. model = run.get_output()[1]

    c. model = run.get_outputs()[0]

    d. model = run.get_outputs()[1]

  2. 您想运行一个预测的ForecastingParameters类吗?

    a. forecast_horizon = 5 * 1

    b. forecast_horizon = 5 * 24

    c. forecast_horizon = 5 * 12

进一步阅读

本节提供了一些有用的网络资源列表,帮助您增加对 AzureML SDK 和本章中使用的各种代码片段的了解:

第十章:第十章:理解模型结果

在本章中,你将学习如何分析机器学习模型的结果,以理解模型为何做出该推断。理解模型为何预测某个值是避免黑箱模型部署的关键,并且能够理解模型可能存在的局限性。在本章中,你将学习 Azure 机器学习的可用解释功能,并可视化模型解释结果。你还将学习如何分析潜在的模型错误,检测模型表现不佳的群体。最后,你将探索一些工具,帮助你评估模型的公平性,并让你能够缓解潜在问题。

本章将涵盖以下主题:

  • 创建负责任的机器学习模型

  • 解释模型的预测

  • 分析模型错误

  • 检测潜在的模型公平性问题

技术要求

你需要拥有一个 Azure 订阅。在该订阅中,你需要有一个名为packt-azureml-rg的资源组。你还需要有ContributorOwner权限的packt-learning-mlw。如果你按照第二章 部署 Azure 机器学习工作区资源中的指引操作,这些资源应该可以获得。

你还需要对Python语言有基本了解。本章中的代码片段针对 Python 3.6 或更高版本。你还应该熟悉在 Azure 机器学习工作室中的 Notebook 体验,这部分内容已在之前的章节中介绍。

本章假设你已经创建了一个名为cpu-sm-cluster的计算集群,如第七章 使用 AzureML Python SDK中“与计算目标协作”部分所述。

你可以在本书的仓库中找到本章的所有 Notebook 和代码片段,链接为bit.ly/dp100-ch10

创建负责任的机器学习模型

机器学习使你能够创建可以影响决策并塑造未来的模型。拥有强大的能力意味着肩负巨大的责任,这也是 AI 治理成为必需的原因,通常被称为负责任的 AI 原则与实践。Azure 机器学习提供了支持负责任 AI 创建的工具,具体体现在以下三个支柱上:

  • 理解:在发布任何机器学习模型之前,你需要能够解释和说明模型的行为。此外,你还需要评估并缓解针对特定群体的潜在模型不公平性。本章重点介绍那些帮助你理解模型的工具。

  • 保护:在这里,你部署了保护个人及其数据的机制。在训练模型时,使用的是来自真实人的数据。例如,在第八章《实验 Python 代码》中,你在糖尿病患者的医疗数据上训练了一个模型。尽管具体的训练数据集没有包含任何个人可识别信息PII),原始数据集却包含了这些敏感信息。有一些开源库,如SmartNoise,提供了基本的构建模块,能够利用经过验证和成熟的差分隐私研究技术来实现数据处理机制。

    例如,使用 SmartNoise 构建的查询引擎可以让数据科学家在敏感数据上执行聚合查询,并在结果中添加统计噪声,以防止意外识别数据集中某一行的单个数据。其他开源库,如presidio,提供了一种不同的数据保护方法,允许你快速识别并匿名化私密信息,如信用卡号、姓名、地点、财务数据等。这些库更多地关注原始文本输入,这是你在构建自然语言处理NLP)模型时通常使用的输入。它们提供了可以用来匿名化数据的模块,便于在训练模型之前处理数据。另一种保护个人及其数据的方法是加密数据,并使用加密数据集进行整个模型训练过程,而无需解密。这可以通过同态加密HE)实现,这是一种加密技术,允许在加密数据上执行某些数学操作,而无需访问私有(解密)密钥。计算结果是加密的,只有私钥的持有者才能揭示。这意味着,使用HE,你可以将两个加密值AB相加,得到一个值C,这个值只能通过加密值AB的私钥解密,如下图所示:

图 10.1 – 使用 HE 在加密数据上执行操作

图 10.1 – 使用 HE 在加密数据上执行操作

  • 控制:控制和记录端到端过程是所有软件工程活动中的一个基本原则。DevOps 实践通常用于确保端到端过程的自动化和治理。DevOps 中的一个关键实践是记录每个步骤中的关键信息,让你在每个阶段做出负责任的决策。Azure 机器学习工作区允许你为你在端到端机器学习过程中的各种工件添加标签和描述。下图展示了你如何为在 第九章 中执行的 AutoML 运行添加描述,优化机器学习模型

图 10.2 – 为运行添加描述以进行文档记录

图 10.2 – 为运行添加描述以进行文档记录

类似于为运行添加描述,你可以为你生产的各种工件(如模型)添加标签。标签是键/值对,例如 PyTorchFramework 标签键的值。你可能希望将以下信息作为模型 数据表 的一部分进行记录:

  • 模型的预期用途

  • 模型架构,包括使用的框架

  • 使用的训练和评估数据

  • 训练模型性能指标

  • 公平性信息,你将在本章中阅读到

这些信息可以作为标签的一部分,而 数据表 可以是一个通过这些标签自动生成的 Markdown 文档。

本节中,你对帮助创建负责任 AI 的工具和技术进行了概述。所有三个支柱同等重要,但对于 DP100 考试,你将专注于理解类别中的工具,从模型可解释性开始,你将在下一节中深入了解。

解释模型的预测结果

能够解释模型的预测结果有助于数据科学家、审计员和商业领袖通过查看驱动模型预测的主要因素来理解模型行为。它还使他们能够进行假设分析,以验证特征对预测的影响。Azure 机器学习工作区与 InterpretML 集成,提供这些功能。

InterpretML 是一个开源社区,提供用于执行模型可解释性的工具。社区包含几个项目,其中最著名的如下:

  • InterpretInterpret-Community 仓库,专注于解释使用表格数据的模型,例如你在本书中所使用的糖尿病数据集。你将在本节中使用 interpret-community 仓库。

  • interpret-text 扩展了解释工作到文本分类模型。

  • 多样化反事实解释DiCE)用于机器学习,可以帮助你检测在数据行中需要进行的最少修改,以改变模型的输出。例如,假设你有一个贷款审批模型,它刚刚拒绝了一笔贷款申请。客户问有什么可以做的来让贷款获得批准。DiCE可以提供批准贷款的最少修改,例如减少信用卡数量或将年薪提高 1%。

解释机器学习模型时有两种方法:

  • DecisionTreeClassifier 提供了 feature_importances_ 属性,允许你理解特征如何影响模型的预测。InterpretML 社区提供了几种更先进的玻璃盒模型实现。这些模型一旦训练完成,允许你获取解释器并查看哪些特征驱动了什么结果,这也被称为可解释性结果。这些模型的解释器是无损的,意味着它们准确地解释了每个特征的重要性。

  • 黑盒解释:如果你训练的模型没有内置的解释器,你可以创建一个黑盒解释器来解释模型的结果。你需要提供训练好的模型和一个测试数据集,解释器会观察特征值的变化如何影响模型的预测。例如,在贷款审批模型中,这可能会调整一个被拒绝记录的年龄和收入,观察这些变化是否会改变预测结果。通过这些实验获取的信息可以用来生成特征重要性的解释。这项技术可以应用于任何机器学习模型,因此被认为是与模型无关的。由于它们的性质,这些解释器是有损的,意味着它们可能无法准确表示每个特征的重要性。在科学文献中,有一些著名的黑盒技术,例如Shapley 加法解释SHAP)、局部可解释模型无关解释LIME)、部分依赖PD)、置换特征重要性PFI)、特征交互莫里斯敏感性分析。黑盒解释器的一个子类别是灰盒解释器,它利用模型结构的相关信息来获得更好、更快的解释。例如,有专门针对树模型(树解释器)、线性模型(线性解释器)甚至深度神经网络(深度解释器)的解释器。

模型解释器可以提供两种类型的解释:

  • 局部实例级特征重要性侧重于特征对特定预测的贡献。例如,它可以帮助回答为什么模型拒绝了某个特定客户的贷款申请。并非所有技术都支持局部解释。例如,基于PFI的方法不支持实例级特征重要性。

  • 全局聚合级特征重要性 解释了模型整体的表现,考虑到模型所做的所有预测。例如,它可以回答哪个特征对于贷款批准来说最为重要。

现在,你已经了解了模型解释的基本理论,是时候获得一些实践经验了。你将从训练一个简单的 sklearn 模型开始。

训练贷款批准模型

在本节中,你将对一个你将生成的贷款批准数据集训练一个分类模型。你将在接下来的章节中使用该模型分析其结果。让我们开始吧:

  1. 导航到 chapter10,然后创建一个名为 chapter10.ipynb 的笔记本,如下所示:图 10.3 – 在 chapter10 文件夹中创建 chapter10 笔记本

    图 10.3 – 在 chapter10 文件夹中创建 chapter10 笔记本

  2. 你需要安装 interpret-community 库的最新包、微软的负责任 AI 小部件,以及 # 或删除该单元格:图 10.4 – 在安装必要的包后重新启动 Jupyter 内核

    图 10.4 – 在安装必要的包后重新启动 Jupyter 内核

  3. 在重新启动内核后,在笔记本中添加一个新单元格。使用以下代码生成一个贷款数据集:

    from sklearn.datasets import make_classification
    import pandas as pd
    import numpy as np
    features, target = make_classification(
        n_samples=500, n_features=3, n_redundant=1, shift=0,
        scale=1,weights=[0.7, 0.3], random_state=1337)
    def fix_series(series, min_val, max_val):
        series = series - min(series)
        series = series / max(series)
        series = series * (max_val - min_val) + min_val
        return series.round(0)
    features[:,0] = fix_series(features[:,0], 0, 10000)
    features[:,1] = fix_series(features[:,1], 0, 10)
    features[:,2] = fix_series(features[:,2], 18, 85)
    classsification_df = pd.DataFrame(features, dtype='int')
    classsification_df.set_axis(
       ['income','credit_cards', 'age'],
       axis=1, inplace=True)
    classsification_df['approved_loan'] = target
    classsification_df.head()
    

    这段代码将生成一个包含以下正态分布特征的数据集:

    • income 的最小值为 0,最大值为 10000

    • credit_cards 的最小值为 0,最大值为 10

    • age 的最小值为 18,最大值为 85

    你将预测的标签是 approved_loan,这是一个布尔值,且在 500 个样本(n_samples)中,只有 30%(weights)是批准的贷款。

  4. 在本章后面,你将针对这个数据集运行一个 AutoML 实验。注册数据集,正如你在 第七章 中看到的,AzureML Python SDK。在你的笔记本中添加以下代码:

    from azureml.core import Workspace, Dataset
    ws = Workspace.from_config()
    dstore = ws.get_default_datastore()
    loans_dataset = \
    Dataset.Tabular.register_pandas_dataframe(
        dataframe=classsification_df,
        target=(dstore,"/samples/loans"),
        name="loans",
        description="A genarated dataset for loans")
    

    如果你访问注册的数据集,可以查看数据集的简介,如下所示:

    图 10.5 – 生成的数据集简介

    图 10.5 – 生成的数据集简介

  5. 为了能够训练和评估模型,你需要将数据集分割成训练集和测试集。使用以下代码来完成此操作:

    from sklearn.model_selection import train_test_split
    X = classsification_df[['income','credit_cards', 'age']]
    y = classsification_df['approved_loan'].values
    x_train, x_test, y_train, y_test = \
            train_test_split(X, y, 
                           test_size=0.2, random_state=42)
    

    首先,将数据集分成两部分,一部分包含特征,另一部分包含你要预测的标签。然后,使用 train_test_split 方法将 500 个样本的数据分割成包含 500 * 0.2 = 100 个测试记录的数据集,以及包含剩余 400 个样本的训练集。

  6. 下一步是初始化模型,并将其拟合到训练数据集。在第九章《优化 ML 模型》中,你学习了 Azure 机器学习的datatransformer步骤是一个ColumnTransformer,它对所有特征应用MinMaxScaler。这个转换器会缩放每个特征的值。

  7. model步骤是你正在训练的实际模型,即RandomForestClassifier

然后,你必须调用已实例化的管道的fit方法,将其训练与训练数据集对齐。

重要提示

你不需要使用Pipeline来受益于本章讨论的可解释性特性。你可以直接通过将模型赋值给model_pipeline变量来使用该模型,例如model_pipeline=RandomForestClassifier()。添加datatransformer步骤是为了帮助你理解 AutoML 是如何构建管道的。使用MinMaxScaler还提高了结果模型的准确性。你可以随意尝试不同的缩放器,以观察结果模型的差异。

  1. 现在你已经有了一个训练好的模型,可以进行测试。让我们测试三个虚构的客户:

    • 一位 45 岁、有两张信用卡、月收入为2000的人。

    • 一位 45 岁、有九张信用卡、月收入为2000的人。

    • 一位 45 岁、有两张信用卡、月收入为10000的人。

    要做到这一点,请在新的笔记本单元格中使用以下代码:

    test_df = pd.DataFrame(data=[
        [2000, 2, 45],
        [2000, 9, 45],
        [10000, 2, 45]
    ], columns= ['income','credit_cards', 'age'])
    test_pred = model_pipeline.predict(test_df)
    print(test_pred)
    

    打印结果是[0 1 1],这意味着第一个客户的贷款将被拒绝,而第二个和第三个客户的贷款将被批准。这表明incomecredit_cards特征可能在模型预测中起着重要作用。

  2. 由于训练后的模型是一个决策树,属于玻璃盒模型类别,你可以获取在训练过程中计算出的特征重要性。使用以下代码在新的笔记本单元格中:

    model_pipeline.named_steps['model'].feature_importances_
    

    这段代码获取实际的RandomForestClassifier实例,并调用feature_importances_。其输出类似于array([0.66935129, 0.11090936, 0.21973935]),这显示income(第一个值)是最重要的特征,但与我们在步骤 7中观察到的情况相比,age(第三个值)似乎比credit_cards(第二个值)更为重要。

    重要提示

    模型的训练过程是非确定性的,这意味着你的结果与书中示例中的结果会有所不同。数值应该相似,但不完全相同。

在本节中,你训练了一个简单的feature_importances_属性。在下一节中,你将使用一种更高级的技术,允许你解释任何模型。

使用表格解释器

到目前为止,你已经使用sklearn库的功能来训练并理解模型的结果。从现在开始,你将使用解释社区的包来更准确地解释你训练好的模型。你将使用SHAP,这是一种黑箱技术,可以告诉你哪些特征在将预测从拒绝转为批准(或反之)的过程中发挥了什么作用。让我们开始吧:

  1. 在一个新的笔记本单元格中,添加以下代码:

    from interpret.ext.blackbox import TabularExplainer
    explainer = TabularExplainer(
                  model_pipeline.named_steps['model'],
                  initialization_examples=x_train, 
                  features= x_train.columns,
                  classes=["Reject", "Approve"],
                  transformations=
                    model_pipeline.named_steps['datatransformer']) 
    

    这段代码创建了一个TabularExplainer,它是 SHAP 解释技术的一个封装类。这意味着该对象会根据传入的模型选择最合适的 SHAP 解释方法。在这种情况下,由于模型是基于树的,它将选择树解释器(tree explainer)。

  2. 使用这个解释器,你将获得局部实例级别的特征重要性,以便更深入地理解模型在训练贷款批准模型部分的步骤 7中为什么会给出这样的结果。在一个新的笔记本单元格中,添加以下代码:

    local_explanation = explainer.explain_local(test_df)
    sorted_local_values = \
        local_explanation.get_ranked_local_values()
    sorted_local_names = \
        local_explanation.get_ranked_local_names()
    for sample_index in range(0,test_df.shape[0]):
        print(f"Test sample number {sample_index+1}")
        print("\t", test_df.iloc[[sample_index]]
                             .to_dict(orient='list'))
        prediction = test_pred[sample_index]
        print("\t", f"The prediction was {prediction}")
        importance_values = \
            sorted_local_values[prediction][sample_index]
        importance_names = \
            sorted_local_names[prediction][sample_index]
        local_importance = dict(zip(importance_names,
                                    importance_values))
        print("\t", "Local feature importance")
        print("\t", local_importance)
    

    这段代码生成了以下截图所示的结果。如果你关注测试样本 2,你会注意到它显示信用卡数credit_cards)是该特定样本被预测为批准预测值为 1)的最重要原因(见0.33的值)。同样样本中收入(其值大约为-0.12)的负值表明该特征推动模型拒绝贷款:

    图 10.6 – 局部重要性特征展示了每个特征对每个测试样本的重要性

    图 10.6 – 局部重要性特征展示了每个特征对每个测试样本的重要性

  3. 你还可以看到收入income)、年龄age)以及信用卡数credit_cards),它们对应的重要性值分别约为0.280.090.06(实际值可能与你的执行结果有所不同)。请注意,这些值与训练贷款批准模型部分的步骤 8中获得的值不同,尽管顺序保持一致。这是正常现象,因为使用方法:shap.tree,这表明TabularExplainer使用树解释器对模型进行了解释,如本节步骤 1所提到的。

  4. 最后,你必须渲染解释仪表板,以查看你在步骤 3中生成的global_explanation结果。在笔记本中添加以下代码:

    from raiwidgets import ExplanationDashboard
    ExplanationDashboard(global_explanation, model_pipeline, dataset=x_test, true_y=y_test)
    

    这将渲染一个交互式小部件,你可以用它来理解模型对你提供的测试数据集的预测。点击特征重要性汇总Aggregate feature importance)标签,你应该会看到在步骤 3中看到的相同结果:

图 10.7 – 解释社区提供的解释仪表板

图 10.7 – 解释社区提供的解释仪表板

你将在查看解释结果部分更详细地探索这个仪表板。

到目前为止,你已经训练了一个模型,并使用 SHAP 解释技术解释了模型预测的特征重要性,无论是在全局还是局部层面上进行特定推理。接下来的部分,你将了解 Interpret-Community 包中可用的其他解释技术。

理解表格数据的解释技术

在上一节中,你使用了表格解释器自动选择了一个可用的 SHAP 技术。目前,解释社区支持以下 SHAP 解释器:

  • Tree explainer 用于解释决策树模型。

  • Linear explainer 解释线性模型,并且也可以解释特征间的相关性。

  • Deep explainer 为深度学习模型提供近似解释。

  • Kernel explainer 是最通用且最慢的解释器。它可以解释任何函数的输出,使其适用于任何模型。

SHAP 解释技术的替代方法是构建一个更容易解释的代理模型,例如解释社区提供的玻璃盒子模型,来重现给定黑盒的输出,并解释该代理模型。这个技术被Mimic 解释器使用,你需要提供以下的一个玻璃盒子模型:

  • LGBMExplainableModel,这是一个 LightGBM(一个基于决策树的快速高效框架)可解释模型

  • LinearExplainableModel,这是一个线性可解释模型

  • SGDExplainableModel,这是一个随机梯度下降可解释模型

  • DecisionTreeExplainableModel,这是一个决策树可解释模型

如果你想在上一节的步骤 1 中使用 Mimic 解释器,代码会像这样:

from interpret.ext.glassbox import (
    LGBMExplainableModel,
    LinearExplainableModel,
    SGDExplainableModel,
    DecisionTreeExplainableModel
)
from interpret.ext.blackbox import MimicExplainer
mimic_explainer = MimicExplainer(
           model=model_pipeline, 
           initialization_examples=x_train,
           explainable_model= DecisionTreeExplainableModel,
           augment_data=True, 
           max_num_of_augmentations=10,
           features=x_train.columns,
           classes=["Reject", "Approve"], 
           model_task='classification')

你可以从第 1 行中的 import 语句中选择任何代理模型。在这个示例中,你使用的是 DecisionTreeExplainableModel。要获取全局解释,代码与在步骤 3 中编写的代码相同,像这样:

mimic_global_explanation = \
       mimic_explainer.explain_global(x_test)
print("Feature names:", 
       mimic_global_explanation.get_ranked_global_names())
print("Feature importances:",
       mimic_global_explanation.get_ranked_global_values())
print(f"Method used: {mimic_explainer._method}")

尽管特征重要性的顺序相同,但计算出来的特征重要性值是不同的,如下所示:

图 10.8 – 使用决策树玻璃盒子模型计算的 Mimic 解释器特征重要性

图 10.8 – 使用决策树玻璃盒子模型计算的 Mimic 解释器特征重要性

类似于 mimic_explainer 使用相同的代码来计算局部实例级别的特征重要性,就像在上一节的步骤 2 中所做的那样。解释可以在以下屏幕截图中看到:

图 10.9 – 使用决策树玻璃盒子模型计算的局部特征重要性 Mimic 解释器的决策树玻璃盒子模型

图 10.9 – 使用 Mimic 解释器的决策树玻璃盒子模型计算的局部特征重要性

Interpret-Community 提供的最后一个解释技术是基于PFI的技术。该技术会通过改变每个特征的值,观察模型预测的变化。要创建一个 PFI 解释器来解释你的模型,你需要以下代码:

from interpret.ext.blackbox import PFIExplainer
pfi_explainer = PFIExplainer(model_pipeline,
                             features=x_train.columns,
                             classes=["Reject", "Approve"])

获取全局解释需要传入true_labels参数,这是数据集的真实标签,即实际值:

pfi_global_explanation = \
        pfi_explainer.explain_global(x_test, 
                                     true_labels=y_test)
print("Feature names:", 
        pfi_global_explanation.get_ranked_global_names())
print("Feature importances:",
        pfi_global_explanation.get_ranked_global_values())
print(f"Method used: {pfi_explainer._method}")

此代码的结果可以在此处查看。由于credit_cardsage特征的重要性值非常相似,结果中它们的顺序可能会互换:

图 10.10 – 通过 PFI 解释器计算的全局特征重要性

图 10.10 – 通过 PFI 解释器计算的全局特征重要性

重要提示

由于PFI 解释器的性质,你不能使用它来创建局部实例级特征重要性。如果在考试中被问到该技术是否能提供局部解释,记住这一点。

在本节中,你了解了 Interpret-Community 包支持的所有解释技术。在下一节中,你将探索解释仪表板所提供的功能,以及该仪表板如何嵌入到 Azure 机器学习工作室中。

审查解释结果

Azure 机器学习与 Interpret-Community 的工作有着丰富的集成点。其中一个集成点是解释仪表板,它嵌入在每个运行中。你可以使用来自azureml.interpret包的ExplanationClient上传和下载模型解释到工作区。如果你使用TabularExplainer使用表格解释器一节中创建了全局解释,导航至chapter10.ipynb笔记本,在文件末尾添加一个新单元格,并输入以下代码:

from azureml.core import Workspace, Experiment
from azureml.interpret import ExplanationClient
ws = Workspace.from_config()
exp = Experiment(workspace=ws, name="chapter10")
run = exp.start_logging()
client = ExplanationClient.from_run(run)
client.upload_model_explanation(
    global_explanation, true_ys= y_test,
    comment='global explanation: TabularExplainer')
run.complete()
print(run.get_portal_url())

这段代码在chapter10实验中启动一个新的运行。通过该运行,你创建一个ExplanationClient,用来上传你生成的模型解释和真实标签(true_ys),这些有助于仪表板评估模型的表现。

如果你访问此代码输出的门户链接,你将进入一个运行页面,在解释标签中,你需要选择左侧的解释 ID,然后访问聚合特征重要性标签以查看解释仪表板,如下所示:

图 10.11 – 审查存储在 Azure 机器学习工作区中的全局解释

图 10.11 – 审查存储在 Azure 机器学习工作区中的全局解释

ExplanationClient由 Azure 机器学习的chapter10.ipynb笔记本使用,并在新单元格中添加以下代码块:

from azureml.core import Workspace, Dataset, Experiment
from azureml.train.automl import AutoMLConfig
ws = Workspace.from_config()
compute_target = ws.compute_targets["cpu-sm-cluster"]
loans_dataset = Dataset.get_by_name(
                            workspace=ws, name='loans')
train_ds,validate_ds = loans_dataset.random_split(
                             percentage=0.8, seed=1337)

这段代码看起来非常类似于你在第九章中使用的代码,优化机器学习模型,位于使用代码运行 AutoML 实验部分。在这段代码中,你正在获取 Azure 机器学习工作区的引用,以及loans数据集,然后将数据集分割为训练集和验证集。

在相同或新建的单元格中,添加以下代码块:

experiment_config = AutoMLConfig(
    task = "classification",
    primary_metric = 'accuracy',
    training_data = train_ds,
    label_column_name = "approved_loan",
    validation_data = validate_ds,
    compute_target = compute_target,
    experiment_timeout_hours = 0.25,
    iterations = 4,
    model_explainability = True)
automl_experiment = Experiment(ws, 'loans-automl')
automl_run = automl_experiment.submit(experiment_config)
automl_run.wait_for_completion(show_output=True)

在这段代码中,你正在启动model_explainability(默认值为True)。这个选项会在AutoML过程完成后安排最佳模型的说明。一旦运行完成,转到该运行的 UI,并打开模型标签,如下图所示:

图 10.12 – AutoML 运行中最佳模型的说明已可用

图 10.12 – AutoML 运行中最佳模型的说明已可用

点击最佳模型的查看说明链接,进入训练该特定模型的子运行的说明标签。当你进入说明标签时,你会注意到AutoML存储了两个全局说明:一个是原始特征的说明,另一个是工程特征的说明。你可以通过选择屏幕左侧的适当 ID,在这两个说明之间切换,如下图所示。原始特征是来自原始数据集的特征。工程特征是经过预处理后得到的特征。这些工程特征是模型的内部输入。如果你选择较低的说明 ID并查看聚合特征重要性区域,你会注意到AutoML已将信用卡号转换为分类特征。此外,与模型训练中产生的三个特征相比,模型的输入是 12 个特征。

你可以在这里查看这些特征及其相应的特征重要性:

图 10.13 – 工程特征的全局说明

图 10.13 – 工程特征的全局说明

由于工程特征较难理解,请转到顶部的说明 ID,这是你目前为止使用的三个原始特征所在的位置。点击数据集浏览器标签,如下图所示:

图 10.14 – 数据集浏览器中的原始特征说明

图 10.14 – 数据集浏览器中的原始特征说明

在这里,我们可以看到以下内容:

  1. Mimic解释器用于解释特定的模型(这是一个XGBoostClassifier,如图 10.12所示)。作为替代模型的glassbox模型是一个LGBMExplainableModel,如前面截图的左上角所示。

  2. 您可以编辑队列或定义新的队列,以便通过从 选择要探索的数据集队列 下拉菜单中选择它们来专注于特定的子组。要定义一个新的队列,您需要指定要应用的数据集过滤条件。例如,在前述截图中,我们定义了一个名为 年龄 _45 的队列,它有一个单一的过滤器(年龄 == 45)。在测试数据集中有 4 个数据点 由此解释仪表板使用。

  3. 您可以通过点击前述截图中标记为 3 的高亮区域来修改 x 轴和 y 轴字段。这使您可以改变视图并获得关于特征与预测值或基本事实之间相关性的见解,特征之间的相关性以及对您的模型理解分析有意义的任何其他视图。

聚合特征重要性选项卡中,如所示,您可以查看您定义的所有数据或特定队列的特征重要性:

Figure 10.15 – Aggregate feature importance for the raw features with 收入依赖性与被拒绝的贷款队列

图 10.15 – 根据收入的原始特征与队列和依赖关系的聚合特征重要性

在本例中,收入 特征对于 年龄 _45 队列比一般公众更重要,由 所有数据 表示。如果您点击特征重要性条,下面的图表会更新,显示这个特征如何影响模型决定拒绝贷款请求(类别 0)。在这个例子中,您可以看到从 0 到略高于 5,000 的收入推动模型拒绝贷款,而从 6,000 开始的收入则产生负面影响,这意味着它们试图推动模型批准贷款。

解释仪表板中有大量的功能,而且随着对解释社区的贡献,新功能会不断出现。在本节中,您回顾了仪表板的最重要功能,这些功能帮助您理解模型为什么会做出预测以及如何可能调试性能不佳的边缘案例。

在下一节中,您将学习错误分析,这是微软整体负责人工智能小部件包的一部分。这个工具允许您了解模型的盲点,即模型表现不佳的情况。

分析模型错误

错误分析 是一种模型评估/调试工具,可以帮助你更深入地了解机器学习模型的错误。错误分析帮助你识别数据集中错误率高于其他记录的群体。你可以更密切地观察被错误分类和有误的数据点,查看是否能发现任何系统性模式,例如是否某些群体没有数据可用。错误分析也是描述当前系统缺陷并与其他利益相关者和审计人员沟通的有效方式。

该工具由多个可视化组件组成,可以帮助你了解错误出现的位置。

导航到 chapter10.ipynb 笔记本。在 菜单 中,点击 编辑器 子菜单下的 在 Jupyter 中编辑,以便在 Jupyter 中打开相同的笔记本并继续编辑,如下所示:

图 10.16 – 在 Jupyter 中编辑笔记本以更好地与小部件兼容

图 10.16 – 在 Jupyter 中编辑笔记本以更好地与小部件兼容

重要说明

在编写本书时,由于笔记本体验的安全限制,错误分析面板无法在笔记本环境中运行,这些限制会妨碍某些功能的正常工作。如果你尝试在笔记本中运行,它不会生成必要的可视化效果。因此,你需要在 Jupyter 中打开笔记本,而这一步在你阅读本书时可能不再需要。

在 Jupyter 环境中,在文件末尾添加一个新的单元格并输入以下代码:

from raiwidgets import ErrorAnalysisDashboard
ErrorAnalysisDashboard(global_explanation, model_pipeline, 
                       dataset=x_test, true_y=y_test)

请注意,这段代码与你用来触发解释面板的代码非常相似。

重要说明

确保你关闭所有其他编辑环境中的笔记本,比如在 Azure 机器学习工作室中的笔记本体验。如果笔记本被其他编辑器意外修改,你可能会丢失部分代码。

该工具以全局视图打开,如下所示:

图 10.17 – 错误分析面板在 Jupyter 环境中的加载情况

图 10.17 – 错误分析面板在 Jupyter 环境中的加载情况

在此视图中,你可以查看模型在整个数据集上的错误率。在这个视图中,你可以看到一棵二叉树,描述了在可解释子群体之间的数据分区,这些子群体具有出乎意料的高或低错误率。在我们的示例中,模型的所有错误都发生在收入小于或等于 6144 的数据中,这占 7.25% 的错误率,意味着 7.25% 的月收入小于 6144 的贷款被错误分类。错误覆盖率是所有错误中落入此节点的部分,在这种情况下,所有错误都位于该节点中(100%)。节点中的数字表示数据的分布情况。这里,69 条记录中有 5 条是错误的,它们属于这个节点。

一旦你选择了树图中的某个节点,你可以点击群体设置群体信息,并将这些记录保存为一个感兴趣的群体。这个群体可以用于解释仪表板。在点击解释按钮后,你将进入数据探索器视图,如下所示:

图 10.18 – 针对树图中选择的特定群体的数据探索器

图 10.18 – 针对树图中选择的特定群体的数据探索器

此视图已经预选了节点的群体。它具有类似于解释仪表板的功能,比如查看影响所选群体整体模型预测的特征重要性。此视图还提供了局部解释标签,允许你理解个别错误记录,甚至进行假设分析,了解模型何时会正确分类该记录。

通过点击小部件左上角的错误探索器链接,你将返回树图视图。在错误探索器:下拉菜单中,选择热力图,而不是当前选中的树图。这将引导你到错误热力图视图,如下所示:

图 10.19 – 错误热力图视图

图 10.19 – 错误热力图视图

此视图根据左上角选定的特征,以一维或二维的方式对数据进行切分。热力图通过较深的红色来可视化具有较高错误的单元格,以引起用户对高错误差异区域的注意。带有条纹的单元格表示没有评估样本,这可能表明存在隐藏的错误区域。

在本节中,我们提供了错误分析仪表板的功能概述,并展示了它如何帮助你理解模型的错误发生位置。该工具可以帮助你识别这些错误区域,并通过设计新特征、收集更好的数据、舍弃部分当前的训练数据,或进行更好的超参数调整来减轻它们。

在接下来的部分,你将了解 Fairlearn,这是一种工具,能帮助你评估模型的公平性并缓解任何观察到的不公平问题。

检测潜在的模型公平性问题

机器学习模型可能由于多种原因表现不公平:

  • 社会中的历史偏见可能会反映在用于训练模型的数据中。

  • 模型开发者所做的决策可能存在偏差。

  • 用于训练模型的数据缺乏代表性。例如,某一特定人群的数据点可能太少。

由于很难确定导致模型表现不公平的实际原因,因此定义模型不公平行为的标准是根据它对人们的影响来判断的。模型可能造成的两种显著伤害类型是:

  • 资源分配损害:这是指模型拒绝为某个群体提供机会、资源或信息。例如,在招聘过程中或我们迄今为止处理的贷款贷款示例中,某些群体可能没有被聘用或获得贷款的机会。

  • 服务质量损害:这是指系统未能为每个人提供相同的服务质量。例如,面部识别在某些人群中的准确度较低。

基于此,很明显,模型公平性问题不能通过自动化解决,因为没有数学公式。Fairlearn是一个工具包,提供帮助评估和缓解分类和回归模型预测公平性的问题的工具。

在我们的案例中,如果将年龄分组视为一个敏感特征,我们可以使用以下代码分析模型基于准确率的行为:

from fairlearn.metrics import MetricFrame
from sklearn.metrics import accuracy_score
y_pred = model_pipeline.predict(x_test)
age = x_test['age']
model_metrics = MetricFrame(accuracy_score, y_test, 
                             y_pred, sensitive_features=age)
print(model_metrics.overall)
print(model_metrics.by_group[model_metrics.by_group < 1])

这段代码获取了你在训练贷款批准模型部分中训练的模型的预测结果,并为x_test数据集生成预测结果。然后,它将x_test['age']特征的所有值分配给age变量。接着,使用MetricFrame,我们可以计算模型的accuracy_score指标,既可以计算整个测试数据集的准确率(存储在overall属性中),也可以按组计算准确率(存储在by_group属性中)。这段代码会打印整体准确率和分组准确率,后者的值小于 1。结果显示在下面的截图中:

图 10.20 – 该模型的准确率为 0.96,但对于 65 岁的人群,其准确率为 0.5

图 10.20 – 该模型的准确率为 0.96,但对于 65 岁的人群,其准确率为 0.5

尽管数据集已经生成,但你可以看到该模型对 65 岁的人群的准确率只有 50%。请注意,尽管该模型是在 18 至 85 岁之间的年龄段进行训练的,但数据集中只检测到 35 个子组,这表明我们可能没有对其进行准确测试。

ExplanationDashboardErrorAnalysisDashboard类似,负责任的 AI 小部件(raiwidgets)包提供了一个FairnessDashboard,可以用来分析模型结果的公平性。

重要提示

在编写本书时,FairnessDashboard在 Jupyter 中工作。在 Notebook 体验中,存在一些技术问题。为了获得最佳体验,请在 Jupyter 中打开你的 Notebook。

在一个新单元格中,添加以下代码以调用公平性仪表板,使用你在前面的代码中定义的年龄敏感特征:

from raiwidgets import FairnessDashboard
FairnessDashboard(sensitive_features=age, 
                  y_true=y_test, y_pred=y_pred)

启动后,该小部件将引导你完成公平性评估过程,在此过程中你需要定义以下内容:

  • 敏感特征:在这里,你必须配置敏感特征。敏感特征用于将数据分组,正如我们之前看到的那样。在这种情况下,它将提示你为年龄组创建五个区间(18-29 岁、30-40 岁、41-52 岁、53-64 岁和 64-75 岁),你可以修改分箱过程,甚至选择提供的视为分类变量选项,以让每个年龄单独处理。

  • 性能指标:性能指标用于评估模型在总体和每个组中的质量。在这种情况下,你可以选择准确度,就像我们之前所做的那样。即使向导完成后,你也可以更改这个选项。

  • 公平性指标:公平性指标表示性能指标的极端值之间的差异或比率,或者仅仅是任何组的最差值。此类指标的一个示例是准确度比率,它是任何两个组之间的最小准确度比率。即使向导完成后,你也可以更改这个选项。

生成的仪表板允许你深入了解模型对各子组的影响。它由两个区域组成——总结表格和可视化区域——你可以在这里选择不同的图形表示方式,如下所示:

图 10.21 – 展示不同年龄组中模型准确度的公平性仪表板

图 10.21 – 展示不同年龄组中模型准确度的公平性仪表板

一旦你确定了模型中的公平性问题,你可以使用Fairlearn库来缓解这些问题。Fairlearn库提供了两种方法:

  • ThresholdOptimizer,调整底层模型的输出以实现显式约束,比如均衡赔率的约束。在我们的二元分类模型中,均衡赔率意味着在各组之间,真正例和假正例的比率应该匹配。

  • sample_weight 参数是 fit sklearn 方法接受的。

使用这些技术,你可以通过牺牲一些模型的性能来平衡模型的公平性,以满足你的业务需求。

Fairlearn包正在不断发展,已经集成到 Azure 机器学习 SDK 和 Studio Web 体验中,允许数据科学家将模型公平性洞察上传到 Azure 机器学习运行历史记录中,并在 Azure 机器学习 Studio 中查看Fairlearn仪表板。

在本节中,你学习了如何检测模型可能存在的潜在不公平行为。你还了解了可以在Fairlearn包中实现的潜在缓解技术。这总结了由 Azure 机器学习工作区和开源社区提供的工具,它们帮助你理解模型并协助你创建人工智能。

总结

本章为你概述了几种可以帮助你理解模型的工具。你首先了解了 Interpret-Community 包,它能够帮助你理解模型做出预测的原因。你学习了各种解释技术,并探索了解释仪表板,其中提供了诸如特征重要性等视图。接着,你看到了错误分析仪表板,它能够帮助你确定模型表现不佳的地方。最后,你学习了公平性评估技术、相应的仪表板,能够让你探索潜在的不公平结果,并了解如何采取措施来缓解潜在的公平性问题。

在下一章,你将学习关于 Azure 机器学习管道的内容,管道可以让你以可重复的方式编排模型训练和模型结果的解释。

问题

在每一章中,你会发现一些问题,帮助你对每章讨论的主题进行知识检查:

  1. 你正在使用 TabularExplainer 来解释 DecisionTreeClassifier。将使用哪种底层的 SHAP 解释器?

    a. DecisionTreeExplainer

    b. TreeExplainer

    c. KernelExplainer

    d. LinearExplainer

  2. 你想使用 MimicExplainer 来解释 DecisionTreeClassifier。你可以使用以下哪种模型作为 explainable_model 参数?

    a. LGBMExplainableModel

    b. LinearExplainableModel

    c. SGDExplainableModel

    d. DecisionTreeExplainableModel

    e. 上述所有选项

  3. 你能使用 PFIExplainer 来生成局部特征重要性值吗?

    a. 是的

    b. 否

进一步阅读

本节提供了一些有用的网络资源,帮助你增强对 Azure 机器学习 SDK 以及本章中使用的各种代码片段的理解:

第十一章:第十一章:使用管道

在本章中,您将学习如何创建可重复使用的过程,定义由多个步骤组成的管道。您可以使用这些管道来创建训练管道,转换数据并训练模型,或者使用它们执行批量推断,使用预训练的模型。一旦注册了这些管道,您可以通过 HTTP 端点或 SDK 调用它们,甚至可以将其配置为按计划执行。掌握这些知识后,您将能够通过使用 Azure 机器学习AzureML)SDK 来实现和使用管道。

在本章中,我们将涵盖以下主要主题:

  • 了解 AzureML 管道

  • 创建管道

  • 发布管道以将其暴露为端点

  • 安排定期执行管道

技术要求

您需要拥有一个 Azure 订阅。在该订阅中,您需要一个 packt-azureml-rg。您需要拥有 ContributorOwner 角色的 packt-learning-mlw,如在 第二章 中的 部署 Azure 机器学习工作区资源 所描述的。

您还需要具备 Python 语言的基本知识。代码片段针对的是 Python 3.6 或更高版本。您还应该熟悉在 AzureML studio 中使用笔记本体验,这一点在 第八章 中的 Python 代码实验 部分有涉及。

本章假设您已经注册了在 第十章 中生成的 loans 数据集,理解模型结果。同时假设您已经创建了名为 cpu-sm-cluster 的计算集群,如在 第七章 中的 使用计算目标 部分所描述的那样,AzureML Python SDK

您可以在 GitHub 上找到本章的所有笔记本和代码片段,网址如下:bit.ly/dp100-ch11

了解 AzureML 管道

第六章 中,可视化模型训练与发布,您已经看到如何使用构建块设计训练过程。类似于这些工作流,AzureML SDK 允许您创建 Pipelines 来协调多个步骤。例如,在本章中,您将创建一个由两步组成的 Pipeline。第一步对 Environment 进行预处理。

重要提示

不要将 Pipelines 与您在 第十章 中阅读的 Pipelines 混淆,理解模型结果Pipelines 是围绕您要训练并用于推断的实际模型类的包装器。

AzureML SDK 提供了许多构建模块,你可以使用它们来构建Pipeline图 11.1包含了你可能在考试和实际代码中遇到的最常用的类:

图 11.1 – 用于编写管道的 AzureML SDK 中的可用类

图 11.1 – 用于编写管道的 AzureML SDK 中的可用类

Pipeline是定义工作流的核心类,它将多个步骤串联在一起。你可以通过使用PipelineParameter类来定义管道参数,并将它们传递给管道。这些参数可以在Pipeline中的一个或多个步骤中引用。一旦定义了管道,你可以将其发布以将其注册到 AzureML 工作区,作为一个版本化对象,并可以通过PublishedPipeline类进行引用。此已发布的管道具有一个端点,你可以使用它来触发其执行。如果需要,你可以定义一个Schedule,并让这个PublishedPipeline类在特定时间间隔触发执行。PipelineData定义了临时存储,允许一个步骤将一些文件放入其中,供下一个步骤使用。这两个步骤之间的数据依赖关系在Pipeline中创建了一个隐式执行顺序,意味着依赖步骤将在第一个步骤完成后等待执行。你将在本章中使用所有这些类。

azureml.pipeline.steps模块中,你将找到所有可用的步骤。最常用的步骤如下:

  • PythonScriptStep:此步骤允许你执行 Python 脚本。你将在本章中使用此步骤。

  • 你在第九章中看到的AutoMLConfig对象,优化机器学习模型

  • 你在第九章中看到的HyperDriveConfig参数,优化机器学习模型

  • DataTransferStep:这是一个Pipeline步骤,允许你在 AzureML 支持的存储选项之间传输数据。

  • DatabricksStep:此步骤允许你在附加的 DataBricks 集群中执行 DataBricks 笔记本、Python 脚本或 JAR 文件。

  • Estimator类代表一个通用的训练脚本。一些框架特定的估算器从这个通用的Estimator类继承,例如TensorFlowPyTorch。要将这些估算器之一纳入你的管道中,你会使用EstimatorStep。整个Estimator类及其派生类已被弃用,取而代之的是ScriptRunConfig,你在前几章中已使用过。如果在考试中看到一个已弃用的EstimatorStep引用,你可以将其视为PythonScriptStep

Pipeline的最后一个重要组成部分是流经其中的数据。

  • (dstore,"/samples/diabetes") 元组用于指示在调用 register_pandas_dataframe 方法时想要存储数据的位置,方法适用于 TabularDataset。你也可以使用等效的 DataPath(datastore=dstore, path_on_datastore="/samples/diabetes") 来代替这个元组。

  • outputs 文件夹会自动上传到 Run 执行中。与该文件夹类似,你可以定义额外的本地文件夹,这些文件夹会自动上传到目标数据存储区中的目标路径。在本章中,你将使用这个类将生成的模型存储在默认 Blob 存储帐户中的特定位置。

  • DataReference 表示数据存储区中的路径,并可用于描述如何以及在哪里在运行时提供数据。它不再是 AzureML 中推荐的数据引用方法。如果你在过时的考试问题中遇到它,你可以将其视为 DataPath 对象。

在这一节中,你了解了可以用来构建 AzureML Pipeline 的构建模块。在下一节中,你将亲自体验使用这些类。

创建管道

假设你需要创建一个可重复的工作流,其中包含两个步骤:

  1. 它从已注册的数据集中加载数据,并将其拆分为训练数据集和测试数据集。这些数据集被转换成 step01 所需的特殊结构。

  2. 它加载预处理过的数据,并训练存储在 AzureML 工作区的默认数据存储区 /models/loans/ 文件夹中的模型。你将在名为 step02 的文件夹中编写此步骤的代码。

    每个步骤将是一个单独的 Python 文件,接受一些参数来指定从哪里读取数据以及将数据写入何处。这些脚本将利用你在 第八章 中编写的相同机制,使用 Python 代码进行实验。本章不同之处在于,你不会单独调用每个 Python 脚本,而是会创建一个 Pipeline,依次调用这些步骤。在 图 11.2 中,你可以看到每个脚本将具有的整体输入和输出,以及你需要为每个步骤配置的参数,以便执行:

图 11.2 – 每个管道步骤的输入和输出

图 11.2 – 每个管道步骤的输入和输出

根据图 11.2,对于每个步骤,你需要定义用于执行特定 Python 脚本的计算目标和Environment。虽然每个步骤可以指定一个单独的计算目标和单独的Environment,但为了简化代码,你将使用相同的Environment和相同的计算目标来运行这两个步骤。你将使用现成的Environment,它包含了标准的数据科学包,包括你的脚本所需的LightGBM库。你将在你在第七章中创建的cpu-sm-cluster集群上执行这些步骤,AzureML Python SDK

你将首先编写Pipeline,然后编写每个步骤所需的实际 Python 脚本。导航到chapter11,然后创建一个名为chapter11.ipynb的笔记本,如图 11.3所示:

图 11.3 – 将 chapter11 笔记本添加到你的工作文件中

图 11.3 – 将 chapter11 笔记本添加到你的工作文件中

打开新创建的笔记本,按照步骤使用 AzureML SDK 编写 AzureML 流水线:

  1. 你将从获取对工作区的引用开始。然后,你将获取对loans数据集和cpu-sm-cluster的引用。在你的笔记本中的一个单元格里添加以下代码:

    from azureml.core import Workspace
    ws = Workspace.from_config()
    loans_ds = ws.datasets['loans']
    compute_target = ws.compute_targets['cpu-sm-cluster']
    

    如果你在理解这段代码时遇到困难,请回顾第七章AzureML Python SDK

  2. 你需要创建一个配置对象,它将在每个步骤执行时决定使用哪个Environment。为此,你需要使用以下代码创建一个RunConfiguration

    from azureml.core import RunConfiguration
    runconfig = RunConfiguration()
    runconfig.environment = ws.environments['RunConfiguration object, and you assign the predefined Environment to its environment attribute. To help you understand how this RunConfiguration object relates to the work you have been doing in *Chapter 8*, *Experimenting with Python Code*, the ScriptRunConfig you have been using in that chapter had an optional run_config parameter where you could have passed this RunConfiguration object you defined in this cell.
    
  3. 接下来,你需要定义一个临时存储文件夹,用于存放第一个步骤的输出文件。你将使用PipelineData类,采用以下代码:

    from azureml.pipeline.core import PipelineData
    step01_output = PipelineData(
        "training_data",
        datastore= ws.get_default_datastore(),
        is_directory=True) 
    

    在这段代码中,你正在创建一个名为training_data的中间数据位置,它被存储为一个文件夹,位于你 AzureML 工作区中注册的默认数据存储中。你不需要关心这个临时数据的实际路径,但如果你感兴趣的话,那个文件夹在默认存储容器中的实际路径类似于azureml/{step01_run_id}/training_data

  4. 现在你已经为流水线的第一步准备好所有的前提条件,是时候定义它了。在一个新的单元格中,添加以下代码:

    from azureml.pipeline.steps import PythonScriptStep
    step_01 = PythonScriptStep(
       'prepare_data.py', 
        source_directory='step01',
        arguments = [
            "--dataset", loans_ds.as_named_input('loans'), 
            "--output-path", step01_output],
        name='Prepare data',
        runconfig=runconfig,
        compute_target=compute_target,
        outputs=[step01_output],
        allow_reuse=True
    )
    

    这段代码定义了一个PythonScriptStep,它将使用step01文件夹中的源代码。它将执行名为prepare_data.py的脚本,并传递以下参数:

    • --dataset: 此参数将loans_ds数据集 ID 传递给该变量。此数据集 ID 是一个唯一的as_named_input方法。此方法在FileDatasetTabularDataset中均可用,并且仅适用于在 AzureML 工作区内执行Run时。要调用该方法,必须提供一个名称,本例中为loans,这个名称可以在脚本内部用于检索数据集。AzureML SDK 将在prepare_data.py脚本中的run对象的input_datasets字典中提供TabularDataset对象的引用。在prepare_data.py脚本中,您可以使用以下代码获取对该数据集的引用:

      run = Run.get_context()
      loans_dataset = run.input_datasets["loans"]
      
    • --output-path: 此参数传递了您在步骤 3中创建的PipelineData对象。该参数将是一个表示脚本可以存储其输出文件的路径字符串。数据存储位置挂载到即将执行特定步骤的计算节点的本地存储上。这个挂载路径被传递给脚本,使您的脚本能够直接将输出透明地写入数据存储。

      回到您传递给PythonScriptStep初始化的参数,您定义了一个名称,该名称将在图 11.6中可见的管道的可视表示中显示。在runconfig参数中,您传递了在步骤 2中定义的RunConfiguration对象。在compute_target参数中,您传递了指向您在步骤 1中获取的cpu-sm-cluster群集的引用。

      outputs参数中,您传递了一个输出数组,该数组将用于此步骤将要发布的数据。这是一个非常重要的参数,用于定义管道中步骤的正确执行顺序。尽管您将PipelineData对象作为参数传递给脚本,但 AzureML SDK 不知道您的脚本是否将从该位置写入或读取数据。通过显式将PipelineData对象添加到outputs参数中,您将此步骤标记为数据存储在PipelineData对象中的生产者。因此,任何在相应inputs参数中引用相同对象的人都需要在此PythonScriptStep之后执行。

      allow_reuse布尔参数允许你在脚本的输入和step01文件夹中的源代码自上次执行管道以来没有更改的情况下重用此PythonScriptStep的输出。由于此步骤的唯一输入是特定版本的TabularDataset,它是不能更改的。尽管你在引用TabularDataset时未指定特定版本,但系统会自动选择最新版本。此版本在管道创建时被固定到管道定义中。即使你创建了TabularDataset的新版本,管道也会继续在固定的版本上执行。此外,由于allow_reuse参数设置为True,此步骤将只执行一次,从那时起,结果将自动重用。在本节的末尾,你将看到这如何影响重新运行相同管道时的管道执行时间。

      重要提示

      如果你想强制管道读取loans_ds变量的最新版本,它将引用TabularDataset的最新版本。在本节的末尾,你还将学习如何将训练数据集作为PipelineParameter传递。

  5. 现在你已经定义了PythonScriptStep,是时候将缺失的 Python 脚本添加到你的文件中了。在你当前工作的chapter11文件夹下,与你的笔记本并列,添加一个名为step01的新文件夹。在该文件夹内,添加一个名为prepare_data.py的新 Python 脚本文件。最终的文件夹结构应类似于图 11.4所示:图 11.4 – 准备数据脚本 prepare_data.py 的文件夹结构,该脚本将在你的管道中执行

    图 11.4 – 准备数据脚本 prepare_data.py 的文件夹结构,该脚本将在你的管道中执行

  6. prepare_data.py文件中添加以下代码块。你可以直接从本章的技术要求部分提到的 GitHub 仓库下载这些代码,而无需手动输入所有代码:

    import argparse
    from azureml.core.run import Run
    from sklearn.model_selection import train_test_split
    import lightgbm as lgb
    import os
    

    这些是你在脚本文件中需要的所有导入。你将使用train_test_split方法为lightgbm库(使用lgb作为短别名)创建训练和测试数据集:

    parser = argparse.ArgumentParser()
    parser.add_argument("--dataset", type=str, dest="dataset")
    parser.add_argument("--output-path", type=str, 
        dest="output_path",
        help="Directory to store datasets")
    args = parser.parse_args()
    

    该脚本创建了一个ArgumentParser,用于解析你在步骤 4中定义PythonScriptStep时传递的参数。提醒一下,--dataset参数将包含脚本需要处理的数据集 ID,而--output-path参数将是脚本应该写入转换后的数据集的本地路径位置:

    run = Run.get_context()
    loans_dataset = run.input_datasets["loans"]
    

    在解析完参数后,你会获得对Run上下文的引用。之后,你会得到对loans数据集的引用,这一点是因为你调用了as_named_input方法,正如第 4 步中所讨论的那样。在本节后续部分,你将了解如何重写这段代码,以便能够在没有Run上下文的本地计算机上运行相同的脚本:

    print(f"Dataset id: {loans_dataset.id}")
    

    这段代码打印了你的代码选择为参考的数据集的 ID。如果你打印传递给--dataset参数的 ID,并且它存储在args.dataset变量中,你会注意到这两个值是相同的:

    loans_df = loans_dataset.to_pandas_dataframe()
    x = loans_df[["income", "credit_cards", "age"]]
    y = loans_df["approved_loan"].values
    feature_names = x.columns.to_list()
    x_train, x_test, y_train, y_test = train_test_split(
        x, y, test_size=0.2, random_state=42, stratify=y
    )
    

    在这段代码中,你将数据集加载到内存中,并使用train_test_split方法将数据集拆分为训练和测试特征(x_trainx_test)以及训练和测试标签(y_trainy_test):

    train_data = lgb.Dataset(x_train, label=y_train, feature_name=feature_names)
    test_data = lgb.Dataset(x_test, label=y_test, reference=train_data)
    

    特征和标签随后被转换为train_datatest_data,它们是Dataset对象。用于训练和验证的Dataset格式。请注意,存储在test_data变量中的验证数据集需要引用训练数据集(train_data)。这是由output_path文件夹嵌入的一个安全机制,如果文件夹不存在,它会先创建,然后使用Dataset的原生save_binary方法将数据集序列化为二进制文件,优化用于存储和加载。

    与在第八章中创建的脚本不同,使用 Python 代码实验prepare_data.py文件无法作为_OfflineRun在本地计算机上执行。这是因为你依赖于input_datasets字典,而这个字典只有在Run在 AzureML 工作区内执行时才可用。如果你想在将该文件用于Pipeline之前在本地测试它,你可以使用以下代码代替:

    run = Run.get_context()
    loans_dataset = None
    if type(run) == _OfflineRun:
        from azureml.core import Workspace, Dataset
        ws = Workspace.from_config()
        if args.dataset in ws.datasets:
            loans_dataset = ws.datasets[args.dataset]
        else:
            loans_dataset = Dataset.get_by_id(ws, args.dataset)
    else:
        loans_dataset = run.input_datasets["loans"]
    

    这段代码检查是否是离线运行。如果是,它首先获取对工作区的引用,正如你在第八章中所看到的那样,使用 Python 代码实验,然后检查存储在args.dataset变量中的--dataset参数是否是数据集名称。如果是,最新版本的数据集会被分配给loans_dataset变量。如果不是名称,脚本会认为它是 GUID,这应该表示特定数据集版本的 ID。在这种情况下,脚本会尝试使用get_by_id方法来检索特定数据集,或者如果传递的值不是已知的数据集 ID,则抛出错误。如果是在线运行,你仍然可以使用input_datasets字典来检索数据集引用。

  7. 回到你的笔记本,你将开始定义第二步的前提条件,即Pipeline的模型训练阶段。在图 11.2中,你看到此步骤需要一个名为learning_rate的参数。你将不再将PipelineParameter的学习率超参数硬编码到代码中,而是将在Pipeline级别定义此参数,并将其作为参数传递给训练脚本,正如你在步骤 9中将看到的那样。要创建这样的参数,请使用以下代码:

    from azureml.pipeline.core import PipelineParameter
    learning_rate_param = PipelineParameter( name="learning_rate", default_value=0.05)
    

    这段代码定义了一个名为learning_rate的新PipelineParameter。默认值为0.05,这意味着在执行管道时可以省略传递此参数,系统将使用默认值。稍后在步骤 13中,你将看到如何执行Pipeline并指定一个不同于默认值的值。

  8. 你将把训练好的模型存储在附加到 AzureML 工作区的默认数据存储的/models/loans/文件夹中。要指定你希望存储文件的确切位置,你将使用OutputFileDatasetConfig类。在一个新的笔记本单元格中,添加以下代码:

    from azureml.data import OutputFileDatasetConfig
    datastore = ws.get_default_datastore()
    step02_output = OutputFileDatasetConfig(
        name = "model_store",
        destination = (datastore, '/models/loans/'))
    

    在此脚本中,你首先获取对默认数据存储的引用。然后,创建一个OutputFileDatasetConfig对象,并将一个元组传递给destination参数。这个元组包含了你选择的数据存储和该数据存储中的路径。你本可以选择任何已附加到 AzureML 工作区的数据存储。这个OutputFileDatasetConfig对象定义了输出的目标位置。如果你没有指定destination参数,系统将使用默认的/dataset/{run-id}/{output-name}值。请注意,destination允许在定义路径时使用占位符。默认值使用了{run-id}{output-name}两个当前支持的占位符。到适当的时刻,这些占位符将被相应的值替换。

  9. 现在你已经定义了所有前提条件,可以定义Pipeline的第二步了。在笔记本的新单元格中,添加以下代码:

    step_02 = PythonScriptStep(
       'train_model.py', 
        source_directory='step02',
        arguments = [
            "--learning-rate", learning_rate_param,
            "--input-path", step01_output,
            "--output-path", step02_output],
        name='Train model',
        runconfig=runconfig,
        compute_target=compute_target,
        inputs=[step01_output],
        outputs=[step02_output]
    )
    

    类似于你在步骤 4中创建的step_01文件夹;这段代码定义了一个PythonScriptStep,它将调用位于step02文件夹中的train_model.py脚本。它将使用你在步骤 7中定义的PipelineParameter传递的值来填充--learning-rate参数。它还会将step_01的输出传递给--input-path参数。请注意,step01_output也被添加到此PythonScriptStep的输入列表中。这意味着step_02必须等待step_01完成,以便消费存储在step01_output中的数据。最后一个脚本参数是--output-path,你将在这里传递你在上一步创建的OutputFileDatasetConfig对象。此对象也被添加到此PythonScriptStep的输出列表中。

  10. 让我们创建一个 Python 脚本,该脚本将在step_02中执行。在你的笔记本旁边,在你当前工作的chapter11文件夹下,创建一个名为step02的新文件夹。在该文件夹内,创建一个名为train_model.py的 Python 脚本文件。最终的文件夹结构应该类似于图 11.5所示:图 11.5 – 将在管道的 step02 文件夹中执行的训练脚本

    图 11.5 – 将在管道的 step02 文件夹中执行的训练脚本

  11. 打开train_model.py文件并添加以下代码块。你可以直接从本章技术要求部分提到的 GitHub 仓库下载这些代码,而不是手动输入。

    import argparse
    import os
    import lightgbm as lgb
    import joblib
    parser = argparse.ArgumentParser()
    

    这段代码导入了文件中需要的所有模块,并创建了一个ArgumentParser来读取你将传递给该脚本的参数。如果你愿意,你也可以使用另一个著名的库来解析脚本参数,称为learning_rate参数。请注意,这是一个浮动值,默认值与你在步骤 7中定义的值不同,这表明这两个默认值不需要相同。在执行管道时,PipelineParameter将定义实际值:

    parser.add_argument(
        "--input-path",
        type=str,
        dest="input_path",
        help="Directory containing the datasets",
        default="../data",
    )
    parser.add_argument(
        "--output-path",
        type=str,
        dest="output_path",
        help="Directory to store model",
        default="./model",
    )
    args = parser.parse_args()
    

    然后你解析input_pathoutput_path,它们是指向执行此脚本的计算机上本地文件夹的字符串值。最后一行解析传入的参数,并将结果分配给args变量:

    print(f"Loading data from {args.input_path}")
    train_data = lgb.Dataset(os.path.join(args.input_path, "train_dataset.bin"))
    validation_data = lgb.Dataset(os.path.join(args.input_path, "validation_dataset.bin"))
    

    解析脚本参数后,训练和验证数据集被加载:

    param = {
        "task": "train",
        "objective": "binary",
        "metric": "auc",
        "num_leaves": 5,
        "learning_rate": args.learning_rate
    }
    model = lgb.train(
        param,
        train_set = train_data,
        valid_sets = validation_data,
        early_stopping_rounds = 5
    )
    

    在这段代码块中,配置了一个二分类训练过程,它将使用auc指标来评估训练进度。early_stopping_rounds参数:

    output_path = args.output_path
    if not os.path.exists(output_path):
        os.makedirs(output_path)
    joblib.dump(value=model, filename=os.path.join(output_path, "model.joblib"))
    

    训练完成后,模型会使用joblib库进行序列化,并存储在output_path文件夹中。

  12. 回到笔记本,是时候定义你目前为止构建的实际Pipeline了。在一个新的单元格中,添加以下代码:

    from azureml.pipeline.core import Pipeline
    pipeline = Pipeline(workspace=ws, steps=[step_01, step_02])
    

    你定义一个新的Pipeline对象,传入包含你要包括的所有步骤的列表。请注意,步骤的顺序并不重要,因为实际的执行顺序是由你在这两个步骤之间指定的step01_output PipelineData依赖关系定义的。

  13. 要执行管道,你需要将其提交到Experiment中。在一个新的笔记本单元格中,添加以下代码:

    from azureml.core import Experiment
    experiment = Experiment(ws, "chapter-11-runs")
    pipeline_run = experiment.submit(
        pipeline,
        pipeline_parameters= {
            "learning_rate" : 0.5
        }
    )
    pipeline_run.wait_for_completion()
    

    这段代码定义了一个新的Experiment,名为chapter-11-runs,并提交管道运行,将0.5的值传递给你在步骤 7中定义的learning_rate参数。

    管道执行的第一个输出之一是指向 AzureML 门户的链接。点击该链接将进入管道执行运行页面,如图 11.6所示:

图 11.6 – 你在本节中创建的管道的图形表示

图 11.6 – 本节中你所编写的管道的图形表示

假设你尝试通过第二次执行你在第 13 步中编写的代码来重新运行管道。在这种情况下,你会注意到执行几乎是即时的(相比第一次执行需要的几分钟,这次只需要几秒钟)。管道检测到没有输入发生变化,并重新使用了先前执行步骤的输出。这展示了第 4 步allow_reuse=True的作用,并且证明了即使我们在第 9 步中没有指定该参数,默认值为True。这意味着,默认情况下,如果输入和代码文件与之前的执行相同,所有步骤都会重用先前的执行结果。如果你想强制重新训练,即使传递给管道的learning_rate变量相同,你可以在第 9 步中指定allow_reuse=False

重要提示

如果你想将训练数据集作为PipelineParameter传递,你需要使用以下代码:

from azureml.data.dataset_consumption_config import DatasetConsumptionConfig

ds_pipeline_param = PipelineParameter(name="dataset ", default_value=loans_ds)

dataset_consumption = DatasetConsumptionConfig("loans", ds_pipeline_param)

使用此代码,并在第 4 步中传递dataset_consumption对象,而不是loans_ds.as_named_input('loans'),将允许你在提交管道执行时选择输入数据集及其版本。

到目前为止,你已经定义了一个执行两个 Python 脚本的管道。step_01预处理训练数据并将其存储在一个中间数据存储中,供step_02使用。之后,第二步将在附加到 AzureML 工作区的默认数据存储的/models/loans/文件夹中训练模型。如果你准确地按照步骤操作,管道应该会成功完成。然而,在实际操作中,编码问题常常会出现,管道可能会未能完成。在下一节中,你将学习如何排查潜在的管道运行时问题。

排查代码问题

到目前为止,你的代码运行得非常顺利。如果某个脚本出现了编码问题或缺少依赖项怎么办?在这种情况下,管道将会失败。在你在图 11.6中看到的图形表示中,你将能够识别出失败的步骤。如果你想获取特定子步骤的详细信息,你必须首先使用pipeline_run对象中的find_step_run来定位它。你可以在笔记本中的新单元格中添加以下代码:

train_step_run = pipeline_run.find_step_run("Train model")[0]
train_step_run.get_details_with_logs()

这段代码查找所有名称为 0 索引的步骤。这将检索一个 StepRun 对象,该对象用于你在上一节中定义的 step_02 文件夹。StepRun 继承自基类 Run,暴露了 get_details_with_logs 方法,该方法也可在你在 第八章 中使用的 ScriptRun 类中找到,使用 Python 代码进行实验。这个方法在排查依赖关系或脚本代码的潜在问题时非常有用。它提供了关于脚本执行的很多有用信息,包括日志文件。

如果你更喜欢 AzureML Studio Web 体验,可以导航到 Pipeline 运行。在管道的图形表示中,选择你想查看日志的步骤。在 输出 + 日志 标签页中查看日志,如 图 11.7 所示:

图 11.7 – 在 Web 门户中查看训练模型步骤的日志

图 11.7 – 在 Web 门户中查看训练模型步骤的日志

到目前为止,你已经学习了如何编写 Pipeline 和如何排查潜在的运行时错误。你创建的 Pipeline 尚未在工作区中注册,接下来你将在下一节进行注册。

将管道发布为端点

到目前为止,你已经使用 AzureML SDK 定义了一个管道。如果你需要重新启动 Jupyter notebook 的内核,你将失去对已定义管道的引用,并且你需要重新运行所有单元格以重新创建管道对象。AzureML SDK 允许你发布管道,从而有效地将其注册为工作区内的版本化对象。一旦管道被发布,就可以在不需要构建它的 Python 代码的情况下提交该管道。

在 notebook 中的新单元格中,添加以下代码:

published_pipeline = pipeline.publish(
    "Loans training pipeline", 
    description="A pipeline to train a LightGBM model")

这段代码发布管道并返回一个 PublishedPipeline 对象,即在工作区中注册的版本化对象。该对象最有趣的属性是 endpoint,它返回用于触发特定管道执行的 REST 端点 URL。

要调用已发布的管道,你将需要一个认证头。要获取此安全头,你可以使用 InteractiveLoginAuthentication 类,如以下代码片段所示:

from azureml.core.authentication import InteractiveLoginAuthentication
auth = InteractiveLoginAuthentication()
aad_token = auth.get_authentication_header()

然后,你可以使用 Python requests 包向特定端点发出 POST 请求,使用以下代码:

import requests
response = requests.post(published_pipeline.endpoint, 
            headers=aad_token, 
            json={"ExperimentName": "chapter-11-runs",
            "ParameterAssignments": {"learning_rate" : 0.02}})
print(f"Made a POST request to {published_pipeline.endpoint} and got {response.status_code}.")
print(f"The portal url for the run is {response.json()['RunUrl']}")

这段代码只需要 URL,而不需要实际的管道代码。如果你丢失了端点 URL,可以通过 PublishedPipeline 类的 list 方法恢复它,该方法列举了工作区中所有已发布的管道。前面的脚本使用 HTTP POST 方法调用 REST 端点,并传递值 0.02 作为 learning_rate 参数。

重要说明

如果你不熟悉 POST 方法(也称为动词),可以在 进一步阅读 部分了解更多信息。

这个 HTTP 请求的结果对象包含有关管道执行的信息,包括RunUrl,它允许你访问 AzureML Studio 门户以监控管道执行。

当你发布管道时,注册的对象会在 AzureML Studio 门户中可用。如果你导航到终端 | 管道终端,你将看到所有已发布管道终端的列表,如图 11.8所示:

图 11.8 – 已发布管道的终端

图 11.8 – 已发布管道的终端

一旦你选择了一个管道,你可以通过图形向导来触发它,向导允许你指定管道参数和管道将要执行的实验。

在本节中,你了解了如何发布管道,以便在不需要管道定义代码的情况下重用它。你看到了如何通过REST终端触发已注册的管道。在下一节中,你将学习如何调度管道以进行每月的再训练。

调度一个重复的管道

通过已发布的REST终端调用管道是非常棒的,尤其是在你有第三方系统需要在特定事件发生后触发训练过程时。例如,假设你正在使用Azure Data Factory从本地数据库复制数据。你可以使用Machine Learning Execute Pipeline活动,触发一个已发布的管道,如图 11.9所示:

图 11.9 – 示例 Azure Data Factory 管道触发一个 AzureML 跟随复制活动的已发布管道

图 11.9 – 示例 Azure Data Factory 管道触发一个跟随复制活动的 AzureML 已发布管道

如果你想调度管道按月触发,你需要像前一节那样发布管道,获取已发布管道的 ID,创建一个ScheduleRecurrence,然后创建Schedule。返回到你的笔记本,在那里你已经有了published_pipeline的引用。添加一个新单元格,并输入以下代码:

from azureml.pipeline.core.schedule import ScheduleRecurrence, Schedule
from datetime import datetime
recurrence = ScheduleRecurrence(frequency="Month", 
                                interval=1, 
                                start_time = datetime.now())
schedule = Schedule.create(workspace=ws,
                  name="chapter-11-schedule",
                  pipeline_id=published_pipeline.id, 
                  experiment_name="chapter-11-scheduled-run",
                  recurrence=recurrence,
                  wait_for_provisioning=True,
                  description="Schedule to retrain model")
print("Created schedule with id: {}".format(schedule.id))

在这段代码中,你定义了一个具有每月频率的ScheduleRecurrence。通过指定start_time = datetime.now(),你防止了管道的立即执行,这是创建新Schedule时的默认行为。一旦你设置了想要的重复模式,可以通过调用Schedule类的create方法来调度管道执行。你将传入你想触发的published_pipeline的 ID,并指定每次执行时所使用的实验名称。

重要提示

安排特定流水线的执行没有任何意义,因为由于两个步骤都设置了 allow_reuse=True,将不会发生任何额外的训练。如果你希望每个月都重新训练,你可能希望将这个设置改为 False,并强制在触发流水线调度时执行两个步骤。此外,在一个定期执行的流水线中,通常第一个步骤会从附加到 AzureML 工作区的多个来源获取新数据,然后转换数据并训练模型。

如果你想禁用定期执行,你可以使用 Schedule 类的 disable 方法。以下代码会禁用工作区中的所有定期流水线:

from azureml.pipeline.core.schedule import Schedule
schedules = Schedule.list(ws, active_only=True) 
print("Your workspace has the following schedules set up:")
for schedule in schedules:
    print(f"Disabling {schedule.id} (Published pipeline: {schedule.pipeline_id}")
    schedule.disable(wait_for_provisioning=True)

这段代码列出了工作区中所有活动的调度,并逐个禁用它们。确保你不会意外禁用本应在工作区中定期执行的流水线。

总结

在本章中,你学习了如何使用 AzureML SDK 定义 AzureML 流水线。这些流水线允许你以可重复的方式协调各种步骤。你首先定义了一个包含两个步骤的训练流水线。接着你学习了如何触发流水线以及如何排查潜在的代码问题。然后你将流水线发布到 AzureML 工作区注册,并获取了一个 HTTP 端点,第三方软件系统可以用来触发流水线执行。在最后一节中,你学习了如何安排已发布流水线的定期执行。

在下一章中,你将学习如何将你迄今为止在书中训练的模型投入生产。你将利用本章所学的知识编写批量推理流水线,这些流水线可以发布并通过 HTTP 触发,或者像本章所学的那样安排执行。

问题

在每一章中,你将找到一些问题来验证你对本章讨论主题的理解。

  1. 什么因素会影响流水线步骤的执行顺序?

    a. 在构建 Pipeline 对象时定义步骤的顺序。

    b. 步骤之间的数据依赖关系。

    c. 所有步骤并行执行,且你无法影响执行顺序。

  2. 判断对错:流水线中的所有步骤都需要在同一个计算目标和 Environment 中执行。

  3. 判断对错:PythonScriptStep 默认情况下会重新使用之前执行的结果,如果参数或代码文件没有发生变化。

  4. 你正在尝试调试一个子任务运行执行问题。你应该在 StepRun 对象中调用以下哪个方法?

    a. get_file_names

    b. get_details_with_logs

    c. get_metrics

    d. get_details

  5. 你刚刚在 Python 代码中定义了一个流水线。你需要做哪些步骤来安排该流水线的每日执行?

深入阅读

本节提供了一些有用的网络资源,以帮助你扩展对 AzureML SDK 和本章中使用的各种代码片段的知识。

第十二章:第十二章:使用代码将模型操作化

在本章中,您将学习如何将您到目前为止在本书中训练的机器学习模型进行操作化。您将探索两种方法:通过托管 REST API 暴露实时端点,您可以用它进行推理;并扩展您的管道编写知识,以高效地在大数据上进行并行推理。您将首先在工作区中注册一个模型以跟踪该工件。然后,您将发布一个 REST API;这将使您的模型能够与第三方应用程序(如Power BI)集成。接下来,您将编写一个管道,以非常具成本效益的方式在几分钟内处理五十万条记录。

在本章中,我们将涵盖以下主题:

  • 了解各种部署选项

  • 在工作区注册模型

  • 部署实时端点

  • 创建批量推理管道

技术要求

您需要访问 Azure 订阅。在该订阅中,您需要一个packt-azureml-rg。您还需要有ContributorOwner权限的packt-learning-mlw。如果您按照第二章部署 Azure 机器学习工作区资源的说明进行操作,这些资源应该已经为您准备好。

此外,您需要具备基本的Python语言知识。本章中的代码片段适用于 Python 3.6 及更高版本。您还应当熟悉在 AzureML Studio 中使用笔记本的操作;这部分内容在第七章The AzureML Python SDK中已有介绍。

本章假设您已在第十章理解模型结果中生成并注册了loans数据集。同时也假设您已按照第七章The AzureML Python SDK中的“与计算目标协作”部分的说明,创建了一个名为cpu-sm-cluster的计算集群。

重要提示

AzureML 不断更新。如果您在使用本书中的代码示例时遇到任何问题,请尝试通过在新笔记本单元格中添加以下代码来升级 AzureML SDK:

!pip install --upgrade azureml-core azureml-sdk[notebooks]

然后,重新启动 Jupyter 内核,如第十章理解模型结果中“训练贷款审批模型”部分所述。此外,尝试从本书的 GitHub 页面下载最新版本的笔记本。如果问题仍然存在,可以在本书的 GitHub 页面上打开问题。

您可以在 GitHub 上的bit.ly/dp100-ch12找到本章所有的笔记本和代码片段。

了解各种部署选项

第八章开始,我们一直在使用 Python 代码,实验 Python 代码。到目前为止,你已经训练了各种模型,基于指标对其进行了评估,并使用joblib库的dump方法保存了训练好的模型。AzureML 工作区允许你通过将它们注册到模型注册表中来存储和管理这些工件,正如我们在第五章中讨论的,让机器进行模型训练。注册模型允许你为保存的模型和与特定模型相关的元数据(如根据各种指标评估的性能)版本化。你将通过 SDK 学习如何在工作区中注册模型部分注册模型。

一旦模型被注册,你需要决定如何操作化模型,是通过部署实时端点还是创建批处理过程,如图 12.1所示:

图 12.1 – 从训练到操作化的路径

图 12.1 – 从训练到操作化的路径

在模型处理传入数据的方式上,主要有两种类别:

  • 你训练的分类器的predict_proba方法。你将在本章的实时端点部署部分深入了解这一场景。

  • 批量推理:在第五章中,让机器进行模型训练,你训练了一个 AutoML 模型来预测客户流失。该模型使用了消费者过去 6 到 12 个月的活动等特征。假设你想评估所有客户并为可能流失的客户开展市场营销活动。你需要执行一次性处理过程,读取所有客户信息,计算所需特征,然后调用模型为每个客户生成预测结果。结果可以存储在 CSV 文件中,供营销部门使用。在这种方法中,你只需要模型短暂的使用时间,即仅在进行预测时。你不需要实时端点,如在第五章中部署的端点,因为你不需要模型进行临时推理。你可以在本章的创建批量推理管道部分了解更多关于这个场景的信息。

所有模型都可以用于实时推理或批处理推理。你可以决定是否需要临时的模型推理,或是一个定期生成并存储推理结果的过程。批处理模式下的模型运营化通常更具成本效益,因为你可以使用低优先级计算集群来进行推理。在这种情况下,你不需要支付实时端点基础设施的费用以等待进行实时推理。

在下一节中,你将通过训练和注册模型,开始迈向模型运营化的道路,该模型将贯穿本章的其余部分。

在工作区中注册模型

注册模型可以让你保留不同版本的训练模型。每个模型版本都包含工件和元数据。在这些元数据中,你可以保留对实验运行和数据集的引用。这使你能够追踪训练模型所使用的数据、训练该模型的运行 ID,以及模型工件本身的谱系,如 图 12.2 所示:

图 12.2 – 从训练数据集到已注册模型的谱系构建

图 12.2 – 从训练数据集到已注册模型的谱系构建

在本节中,你将训练一个模型并将其注册到你的 AzureML 工作区中。请执行以下步骤:

  1. 进入你的 AzureML Studio Web 界面中的Notebooks部分。

  2. 创建一个名为 chapter12 的文件夹,然后创建一个名为 chapter12.ipynb 的笔记本,如 图 12.3 所示:图 12.3 – 将 chapter12 笔记本添加到你的工作文件中

    图 12.3 – 将 chapter12 笔记本添加到你的工作文件中

  3. 在单独的笔记本单元格中添加并执行以下代码片段。你将从获取工作区资源的引用开始:

    from azureml.core import Workspace, Experiment
    ws = Workspace.from_config()
    loans_ds = ws.datasets['loans']
    experiment = Experiment(ws, "chapter-12-train")
    

    在前面的代码中,你获取了工作区的引用,即 chapter-12-train

  4. 使用以下代码将数据集拆分为训练集和验证集:

    training_data, validation_data = loans_ds.random_split(
                           percentage = 0.8, seed=42)
    X_train = training_data.drop_columns('approved_loan') \
                .to_pandas_dataframe()
    y_train = training_data.keep_columns('approved_loan') \
                .to_pandas_dataframe().values.ravel()
    X_validate = validation_data.drop_columns('approved_loan') \
                    .to_pandas_dataframe()
    y_validate = validation_data.keep_columns('approved_loan') \
                    .to_pandas_dataframe().values.ravel()
    

    代码将数据集拆分为 80% 的训练数据和 20% 的验证数据。seed 参数初始化 random_split 方法的内部随机状态,允许你硬编码数据拆分,并确保每次调用此代码时生成相同的 training_datavalidation_data

    在这里,X_train 是一个 pandas DataFrame,包含 incomecredit_cardsage 特征(即除 approved_loan 外的所有列)。

    相比之下,y_train包含的是你想要预测的值。首先,你加载一个只包含approved_loan列的pandas DataFrame。然后,你将该DataFrame转换为values属性。这个数组对每一行都有一个单一元素数组。例如,[[0],[1]]表示两个记录:一个未批准的贷款值为0,一个已批准的贷款值为1。接着,你调用ravel方法来扁平化这个数组,这样给定的例子就变成了[0, 1]。尽管你本可以直接使用pandas DataFrame来训练模型,但系统会发出警告消息,提示你已进行自动转换,并建议你使用ravel方法,正如在这个单元中所看到的那样。

    对于将用于评估模型性能的X_validate DataFramey_validate数组,重复相同的过程。

  5. 使用以下代码训练一个模型并记录得到的准确性:

    from sklearn.linear_model import LogisticRegression
    from sklearn.metrics import accuracy_score
    run = experiment.start_logging()
    sk_model = LogisticRegression()
    sk_model.fit(X_train, y_train)
    y_predicted = sk_model.predict(X_validate)
    accuracy = accuracy_score(y_validate, y_predicted)
    print(accuracy)
    run.log("accuracy", accuracy)
    run.complete()
    

    在这里,你从实验中的一次运行开始,如步骤 3所定义。你将使用这次运行来注册模型训练过程中的指标、日志和工件。然后,你训练一个LogisticRegression模型,并使用accuracy_score函数来计算训练后模型的准确性。接着,你打印出计算得到的准确性,并将其作为指标记录到运行中。最后,你complete该运行,以结束其执行。

  6. 现在你有一个由sk_model变量引用的训练模型,你将使用以下代码将其保存:

    import os
    import joblib
    os.makedirs('./model', exist_ok=True)
    joblib.dump(value=sk_model,
                filename=
                  os.path.join('./model/','model.joblib'))
    

    首先,你创建一个名为model的文件夹。文件夹的名称不重要。在该文件夹中,你使用joblib库将训练好的模型dump到一个名为model.joblib的文件中。

    重要提示

    .joblib文件扩展名不是标准的,你可以根据自己的需要使用任何名称,只要保持一致即可。有些人使用.pkl作为文件扩展名,这在过去是因为我们使用 Python 的内置pickle模块序列化 Python 对象结构。如今,scikit-learn推荐使用joblib库,因为它在序列化大型 NumPy 数组时更加高效,而这在训练模型时非常常见。

  7. 现在你已经准备好工件,可以使用以下代码注册模型:

    from sklearn import __version__ as sk_version
    from azureml.core import Model
    run.upload_folder("model", "./model")
    model = run.register_model(
            model_name="chapter12-loans",
            model_path="./model/",
            tags={ "accuracy": accuracy},
            properties={ "accuracy": accuracy},
            model_framework= Model.Framework.SCIKITLEARN,
            model_framework_version= sk_version,
            datasets=[("training", loans_ds)]
    )
    

    在第一行,你导入sklearn包的__version__变量,它是一个字符串,表示当前环境中加载的版本。然后,你为该变量创建一个别名(使用as语句),并在代码中将其作为sk_version引用。这就是你用来训练模型的sklearn库的版本。此外,你还从 AzureML SDK 导入Model类,以便在后续的代码中使用它作为参考。

    导入引用之后,您上传本地./model文件夹的内容,该文件夹在Step 6中创建,到运行的输出中,位于名为model的文件夹下。这样 AzureML 可以访问您即将注册的工件;否则,您将收到ModelPathNotFoundException错误。

    准备好所有先决条件后,您可以注册模型。模型将以chapter12-loansmodel_name 参数)命名,使用刚刚上传到运行输出的model文件夹中的工件(model_path 参数)。您将精度指定为模型的标签(tags 参数)和属性(properties 参数)。您指示使用SCIKITLEARN框架(model_framework 参数)训练模型,并指定您使用的框架版本(model_framework_version 参数)。在最后一行,您指定使用loans_ds数据集作为training数据集(datasets 参数)。

    重要说明

    如果尝试重新运行相同单元格,则会发生Resource Conflict错误,因为无法覆盖已存在于运行输出文件夹中的文件。如果使用#作为行前缀注释掉upload_folder行并重新运行单元格,则会注册同一模型的新版本,使用已存在于特定运行中的工件。

  8. 导航至Model.Framework.SCIKITLEARN。这种部署类型被认为是无代码部署,这是 AzureML 为支持的框架提供的能力。否则,您需要指定一个评分文件;这是我们将在Deploying real-time endpoints部分中涵盖的内容。

  9. 如果要注册从互联网下载的预训练模型,则没有Run对象来调用register_model方法。您可以使用Model类的register方法,如下面的代码片段所示:

    from azureml.core import Model
    offline_model = Model.register(
            ws,
            model_name="chapter12-pre-trained-loans",
            model_path="./model/",
            properties={"accuracy": 0.828},
            model_framework= "ScikitLearn",
            model_framework_version= "0.22.2.post1"
    ) 
    

    在上述代码中,在 AzureML 工作区(ws变量)中注册位于local model文件夹内部的工件(model_path 参数)作为名为chapter12-pre-trained-loans的模型(model_name 参数)。这是使用sklearn库的版本0.22.2.post1model_framework_version 参数)训练的模型。另外,其精度为0.828,存储为模型属性。

  10. 如果有一个训练新模型的流程,例如您在Chapter 11中创建的计划管道,您需要验证新训练的模型是否比已注册的模型具有更好的指标。如果更好,则继续注册模型。为此,您可以使用类似以下代码的代码:

    from sklearn.linear_model import RidgeClassifier
    new_model = RidgeClassifier(solver='svd')
    new_model.fit(X_train, y_train)
    y_predicted = new_model.predict(X_validate)
    accuracy = accuracy_score(y_validate, y_predicted)
    registered_model = Model(ws, name="chapter12-loans")
    r_version = registered_model.version
    r_acc = float(registered_model.properties['accuracy'])
    if accuracy > r_acc:
        print(f"New model has better accuracy {accuracy}")
    else:
        print(f"Registered model with version {r_version}" \
               " has better accuracy {r_acc}")
    

    在前面的代码中,你训练了一个基于 RidgeClassifier 的模型,使用的是你在 第 7 步 中注册的 chapter12-loansregistered_model 变量与 第 7 步 中获得的 model 变量具有相同的引用;不过,这次你是通过 Model 类创建该引用,而不是通过注册模型来创建。你从该模型中读取 version 属性和 accuracy 属性。你可以从模型的 tags 字典中检索准确度,而不是从 properties 字典中。由于标签和属性以字符串形式存储值,因此你需要将准确度值转换为浮动类型。接下来,你将新模型的准确度与已注册模型的准确度进行比较(已注册模型的准确度存储在 r_acc 变量中)。如果新模型优于已注册的模型,则会打印一条消息。在这种情况下,你需要重复 第 6 步第 7 步 来存储模型,并注册新版本的改进模型。

    重要提示

    要注册一个新版本的模型,你只需使用相同的名称注册新模型。通过使用相同的名称注册新模型,AzureML 会自动为你创建一个新版本。

  11. 可选地,作为最后一步,使用以下代码删除本地存储的模型:

    import shutil
    shutil.rmtree('./model',ignore_errors=True)
    

    这段代码会删除你在 第 6 步 中创建的 model 文件夹,包括你不再需要的序列化模型。ignore_errors 参数允许你即使文件夹不存在也能运行此单元,而不会引发错误。

在本节中,你在 Jupyter 内核中训练了一个模型。然后,你在工作区内注册了该模型。你本可以在 train_model.py 脚本中使用相同的注册代码,这个脚本是你在第十一章中的 创建管道 部分的 第 11 步 中编写的,与管道一起工作,用来注册 run=Run.get_context() 方法,然后你需要上传序列化的模型并注册模型,就像你在 第 7 步 中所做的那样。作为额外的活动,尝试修改 train_model.py 脚本和 chapter11.ipynb,创建一个管道,将正在训练的模型在管道中进行注册。此活动的潜在解决方案可以在 train_model_and_register.py 脚本中找到,位于 GitHub 仓库的 step02 文件夹中,链接为:bit.ly/dp100-ch11

在下一节中,你将开始将本节中注册的模型转化为可操作的模型,通过将其部署为一个 Web 服务来提供实时推断服务。

部署实时端点

假设你有一个电子银行解决方案,其中包含一个让客户申请贷款的流程。你希望适当地设定客户的预期,并为可能的拒绝做准备。当客户提交贷款申请表时,你希望调用你在在工作区注册模型部分中注册的模型,即名为chapter12-loans的模型,并传入客户在申请表上填写的信息。如果模型预测贷款将不会被批准,贷款请求的确认页面将出现一条消息,提醒客户贷款请求可能会被拒绝。

图 12.5展示了一个过于简化的架构,用以描绘从客户到模型实时端点的请求流向:

图 12.5 – 一个过于简化的电子银行架构,展示了请求流向从客户到模型的请求流向

图 12.5 – 一个过于简化的电子银行架构,展示了从客户到模型的请求流向

部署模型最简单的方法是通过 AzureML 提供的无代码部署方式,适用于特定的机器学习框架,包括你在上一部分中使用的sklearn库。请按照以下步骤操作:

  1. 转到chapter12.ipynb笔记本,添加以下代码以获取对你在上一部分中创建的chapter12-loans模型的最新版本的引用:

    from azureml.core import Workspace, Model
    ws = Workspace.from_config()
    model = Model(ws, name="chapter12-loans")
    
  2. 要部署实时端点,请使用以下代码:

    no_code_service = Model.deploy(ws, "no-code-loans",
                                   [model])
    no_code_service.wait_for_deployment(show_output=True)
    

    该代码部署一个名为no-code-loans的新实时端点服务,然后等待部署完成。

  3. 要获取新部署的端点的评分 URI,请使用以下代码:

    print(no_code_service.scoring_uri)
    

    这是一个格式为guid.region.azurecontainer.io/score的 URL,接受带有JSON负载的POST请求,如下所示:

    {"data": [[2000,2,45]]}
    

    该负载将触发一个推理请求,针对一位月收入 2000 美元、拥有 2 张信用卡并且 45 岁的客户。你可以使用Postmancurl等工具来构造这样的 HTTP 请求,并调用端点。

  4. 与其使用如curl之类的工具发起 HTTP 请求,你还可以使用no_code_service引用,并通过传入通常会发送给服务的 JSON 负载来调用run方法:

    import json
    input_payload = json.dumps({
        'data': [[2000, 2, 45], [2000, 9, 45]],
        'method': 'predict'
    })
    output = no_code_service.run(input_payload)
    print(output)
    

    上述代码导入了json库,它帮助你将对象序列化为 JSON 字符串。你使用dumps方法创建负载。请注意,这个负载与步骤 3中你看到的简单版本略有不同。在这个示例中,你传递了两个客户的信息:一个是之前传递的客户,另一个拥有9张信用卡,而不是2张。此外,你还指定了要调用的方法。默认情况下,模型的方法名是predict,这是你在前几章中用来进行推理的方法。最后,你打印输出,应该看到类似以下的结果:

    {'predict': [0, 1]}
    

    上述结果显示,第一个贷款将被拒绝,而第二个贷款将被批准。

    大多数分类模型提供了另一种方法,叫做predict_proba,它返回一个包含每个标签概率的数组。在loans审批的情况下,这个数组只包含两个概率,且总和为 1,也就是贷款被批准的概率和贷款被拒绝的概率。如果你将方法名从predict更改为predict_proba并重新执行单元格,你将得到以下结果:

    {'predict_proba': [[0.998, 0.002], [0.173, 0.827]]}
    

    上述结果显示,模型 99.8%确定第一个贷款将被拒绝,82.7%确定第二个贷款将被批准。

  5. 可选地,导航到chapter12-demanding-loans。你指定它需要1个 CPU 和1.5GB 的 RAM。请注意,如果你在步骤 11中的在工作区注册模型部分删除了model文件夹,那么这段代码将无法注册新模型,因为它找不到模型文件。

  6. 为了节省成本,你应该使用以下代码删除服务:

    no_code_service.delete()
    

到目前为止,你已经使用无代码方法部署了一个实时端点,这种方法将模型作为容器实例进行部署。只有当模型使用特定的支持模型进行训练时,这种方法才可行。在下一部分,你将学习如何使用更高级的选项来部署模型。

理解模型部署选项

在前面的部分,你使用无代码的方法部署了一个模型。在幕后,AzureML 使用了一个包含所有必需模型依赖项的environment,在我们的例子中是sklearn,生成了一个 Python 脚本,用于加载模型并在数据到达端点时进行推理,并使用AciServiceDeploymentConfiguration类发布了一个 ACI 服务。

如果你有一个使用不支持的框架训练的模型,或者你想更好地控制部署模型,你可以使用 AzureML SDK 类来部署模型,如图 12.7所示:

图 12.7 – 实时端点部署所需的组件

图 12.7 – 实时端点部署所需的组件

这里,InferenceConfig类指定了模型的依赖项。它需要一个入口脚本,该脚本将加载模型并处理传入的请求,以及一个脚本执行环境。该环境包含模型加载和进行推断所需的所有依赖项。

入口脚本应包含以下两个方法:

  • Init:在此步骤中,脚本将训练好的模型加载到内存中。根据您将模型的状态存储到磁盘的方式,您可以使用相应的方法将模型反序列化。例如,如果您使用joblib库序列化了模型,则可以使用相同库的load方法将其加载到内存中。一些模型提供自己的序列化和反序列化方法,但过程保持一致;训练好的模型的状态保存在一个或多个文件中,您可以稍后使用这些文件将模型加载到内存中。根据模型的大小,初始化阶段可能需要相当长的时间。较小的sklearn模型通常在几毫秒内加载到内存中,而较大的神经网络可能需要几秒钟的时间来加载。

  • run:这是实时端点接收数据集以进行推断时调用的方法。在此方法中,您必须使用init代码中加载的模型,调用它提供的预测方法,对传入的数据进行推断。如前所述,大多数模型提供predict方法,您可以调用并将要进行推断的数据传入。大多数分类模型还提供一个附加方法,称为predict_proba,它返回每个类别的概率。AutoML 预测模型提供forecast方法,而不是predict方法。在神经网络中,进行预测的方法有所不同。例如,在 TensorFlow 的第一个版本中,您必须通过session.run()方法调用来进行预测。

一旦配置了模型依赖项,您需要决定将模型部署到何处。AzureML SDK 提供了三种类:LocalWebserviceDeploymentConfigurationAciServiceDeploymentConfigurationAksServiceDeploymentConfiguration。这些类允许您将模型部署到本地机器、ACI 或Azure Kubernetes 服务AKS),如图 12.8所示:

图 12.8 – 为您的模型选择合适的计算目标

图 12.8 – 为您的模型选择合适的计算目标

正如您可能已经理解的那样,在图 12.8中,您可以通过指定您希望服务监听的端口来部署到本地计算机。这是一种很好的方法,可以调试模型加载的潜在问题,或验证与本地计算机上其他系统的集成。下一个选项是使用 ACI,它用于测试环境或小规模的生产环境。在AciServiceDeploymentConfiguration类中,您只能使用 CPU,而不能使用 GPU。您可以通过将auth_enabled参数设置为True来使用基于密钥的认证保护端点。此认证方法要求您将静态密钥作为Authorization头部传递到 HTTP 请求中。

另一方面,AksServiceDeploymentConfiguration将在 AKS 集群内部署服务。这使得您可以使用 GPU,前提是您的模型能够利用 GPU,并且您要部署的集群有支持 GPU 的节点。该部署配置允许您选择基于密钥的认证或基于令牌的认证。基于令牌的认证要求最终用户从保护 AzureML 工作区的Azure Active Directory获取访问令牌,这样就可以访问部署在其中的端点。与基于密钥的认证不同,基于令牌的认证令牌生命周期较短,并隐藏了调用者的身份,而基于密钥的认证是 ACI 中唯一可用的选项。AKS 部署的另一个生产就绪特性是能够根据传入请求数量的波动动态扩展和缩减。在当前的电子银行场景中,客户倾向于在工作时间访问电子银行解决方案,而在夜间系统几乎处于空闲状态。此外,在月底,传入流量会达到峰值。在这种工作负载下,您希望能够根据需要扩展端点,以适应流量的增加。当流量显著增加时,AKS 可以自动启动多个模型容器,并在它们之间进行负载均衡。当流量恢复正常时,它可以仅保留一个容器作为潜在流量的热备份。

现在,您对部署选项有了更好的理解,接下来您将使用在图 12.7中看到的类,在 ACI 中部署相同的模型:

  1. 首先,您需要创建的是入口脚本。在chapter12文件夹下,创建一个名为script的新文件夹,并将一个score.py文件放入其中,如图 12.9所示:图 12.9 – 为实时端点添加 score.py 文件

    图 12.9 – 为实时端点添加 score.py 文件

  2. init方法中,你通过AZUREML_MODEL_DIR环境变量获取序列化模型的路径。当 AzureML 启动用于提供模型的 Docker 镜像时,该变量指向模型所在的文件夹;例如,/tmp/azureml_umso8bpm/chapter12-loans/1可能是你找到chapter12-loans模型第一版的地方。在该文件夹中,实际的文件model.joblib位于你在部署实时端点部分的步骤 5中上传的model文件夹中。你使用os.path.join来获取模型的最终路径,然后将模型加载到名为modelglobal变量中。如果你想使用 AzureML SDK 来获取模型的位置,你可以使用model_path = Model.get_model_path(model_name, version=version),该方法在底层使用相同的环境变量。然而,请注意,你需要在环境中安装 AzureML SDK,以便能够导入其中的Model类;而前面的代码不需要这么做。

    重要说明

    请注意,你正在使用print将模型路径和传入的raw_data写入控制台。你将在通过应用程序洞察进行监控部分学习如何查看这些消息。

    run方法中,你使用try except块来捕捉在尝试读取请求输入时可能发生的错误。如果发生这样的错误,异常会被序列化为字符串(使用str()方法),并返回给最终用户。请注意,将异常返回给调用者是一种安全反模式,因为你可能会不小心向潜在的攻击者暴露有价值的信息,但在调试时这非常有用。你可以使用print语句或者更高级的库来代替返回错误消息,例如try块,在该块中,你会反序列化传入的 JSON 负载,如部署实时端点部分的步骤 3所示。然后,你调用通过init方法加载到内存中的model对象的predict方法。接着,你将模型结果作为一个列表返回,并将其序列化为数组。

    重要说明

    你永远不会直接调用init方法或run方法。AzureML 会在最终的 Docker 镜像中放入另一段代码,那就是 HTTP 推理服务器。该服务器负责在服务器启动时调用你的init方法,并将传入的 HTTP 数据传递到run方法中。此外,你在run方法中返回的结果将被序列化为JSON并返回给调用者。

  3. 接下来你需要的是一个包含所有必要依赖项的Environment,用于运行你创建的score.py脚本。打开你的chapter12.ipynb笔记本并在新单元格中添加以下代码:

    from azureml.core import Environment
    from azureml.core.conda_dependencies import CondaDependencies 
    import sklearn
    myEnv= Environment(name="sklearn-inference")
    myEnv.Python.conda_dependencies = CondaDependencies()
    myEnv.Python.conda_dependencies.add_conda_package(
                   f"scikit-learn=={sklearn.__version__}")
    myEnv.Python.conda_dependencies.add_pip_package(
                   "azureml-defaults>=1.0.45")
    

    在前面的代码中,你创建了一个Environment,如在第八章中演示的,使用 Python 代码进行实验。你添加了scikit-learnazureml-defaultspip包,这些包包含了将模型作为 Web 服务托管所需的功能。由于你正在构建自己的Environment,因此需要添加此包,并至少使用 1.0.45 版本。这是运行评分脚本时你可以使用的最低环境。此外,AzureML 还提供了一个已策划的环境,例如AzureML-sklearn-0.24.1-ubuntu18.04-py37-cpu-inference,它包含了使用训练过的sklearn模型(版本 0.24.1)进行推理请求所需的一切。

  4. 你已经定义了InferenceConfig类所需的一切。添加一个新的单元格,并输入以下代码以将所有内容组合起来:

    from azureml.core.model import InferenceConfig
    inference_config = InferenceConfig(
                          source_directory= "./script",
                          entry_script='score.py', 
                          environment=myEnv)
    

    这段代码创建了你在模型推理时所需要的配置。它使用位于script文件夹中的score.py文件,并在步骤 3中定义的myEnv环境中执行该文件。

  5. 现在你已经完成了图 12.7中所示的三个组件中的两个。在此步骤中,你将创建一个AciServiceDeploymentConfiguration类,并将模型部署到 ACI。在新单元格中,添加以下代码:

    from azureml.core.webservice import AciWebservice
    deployment_config = AciWebservice.deploy_configuration(
                        cpu_cores=1, memory_gb=1)
    service = Model.deploy(ws, "aci-loans", [model], 
                    inference_config, deployment_config)
    service.wait_for_deployment(show_output=True)
    

    在这里,我们使用AciWebservice类来获取你想要部署的容器实例的部署配置。在前面的代码中,你指定了需要 1 个 CPU 核心和 1GB 的内存。然后,你将模型部署到一个名为aci-loans的新服务中,并等待部署完成。

    重要提示

    如果在尝试部署容器时遇到问题,你可以查看打印输出中的错误信息,或使用service.get_logs()方法。很可能是score.py脚本中的代码库出现了问题。你可以通过安装azureml-inference-server-http pip 包并运行以下命令来在本地测试代码:

    5001。调试这种情况的另一种方法是使用LocalWebservice,稍后我们将讨论。如果你的代码没有问题,那么可能是内存问题。这应该可以在服务日志中看到。在这种情况下,请参阅下一节,了解如何对模型进行分析,以确定其资源需求。

  6. 要测试已部署的服务,你可以使用以下代码,这与前一节中使用的代码类似:

    import json
    input_payload = json.dumps({
        'data': [[2000, 2, 45]]
    })
    output = service.run(input_payload)
    print(output)
    

    请注意,负载中的method属性(你在步骤 4中使用的部署实时端点部分)不会对这次部署产生任何影响,并且会从负载中省略。如果你想支持此属性,则需要在score.py文件的run方法中编写代码来读取该属性并调用模型的相应方法。

  7. 为了节省成本,在完成测试后使用以下代码删除服务:

    service.delete()
    
  8. 如果你想在本地计算机上部署相同的服务,可以使用以下代码:

    from azureml.core.webservice import LocalWebservice
    deployment_config = LocalWebservice.deploy_configuration(port=1337)
    service = Model.deploy(ws, "local-loans", [model], inference_config, deployment_config)
    service.wait_for_deployment()
    

    你不再使用AciWebservice类,而是使用LocalWebservice来创建一个监听端口1337的本地服务。如果你在本地计算机上运行笔记本,你需要访问http://localhost:1337并查看服务端点的健康状况。现在,在 AzureML 笔记本中运行了这段代码,本地计算机就是你正在使用的计算实例。要查看名为service.delete()的计算实例的端口1337,请参见步骤 7

类似于AciWebserviceLocalWebservice,你还可以使用AksWebservice来创建AksServiceDeploymentConfiguration。在部署时,你需要在Model.deploy方法中指定一个额外的参数,即deployment_target参数。这个参数允许你指定想要将模型部署到的AksCompute推理集群。

除了你之前看到的本地计算机、ACI 和 AKS 部署选项,AzureML 还提供了多种其他部署选项。例如,Azure Functions允许你在无服务器架构中运行模型,Azure App Services将模型托管为传统的 Web 应用程序,随时准备处理传入的请求。另一方面,你可以使用IoT Edge,它允许你将服务部署到边缘设备,如树莓派或基于 GPU 的 Jetson Nano。最后,你甚至可以将模型打包到 Docker 容器镜像中,这可以在隔离的空气间数据中心内运行。

在本节中,你已部署了一个 ACI 实时推理端点,要求 1 个 CPU 核心和 1 GB 的内存。在接下来的章节中,你将探讨如何通过对模型性能的分析来优化资源需求。

对模型资源需求的分析

在将某些东西投入生产之前,执行压力测试是非常常见的做法。本质上,这种测试会向实时端点发送大量请求,并衡量该端点的响应能力和性能。你可以对模型进行类似的操作,了解它们在预期的性能下需要什么类型的资源。例如,你可能需要确保所有推理都在 200 毫秒内完成。

在本节中,你将创建一个测试数据集,该数据集将用于压力测试实时端点并观察其性能。数据集中的每一行将包含一个单独的推理请求。

打开你的chapter12.ipynb笔记本,并执行以下步骤:

  1. 在一个新单元格中,添加以下代码:

    loans_ds = ws.datasets['loans']
    prof_df = loans_ds.drop_columns('approved_loan') \
                            .to_pandas_dataframe()
    prof_df['sample_request'] = \
        "{'data':[[" + prof_df['income'].map(str) \
      + ","+ prof_df['credit_cards'].map(str) \
      + "," + prof_df['age'].map(str) + "]]}"
    prof_df = prof_df[['sample_request']]
    prof_df.head()
    

    这段代码加载loans数据集,删除我们不需要的approved_loan列,并将其加载到pandasDataFrame中。接着,你创建一个名为sample_request的新列,将各个列连接起来,生成如下字符串:

    {"data": [[2000,2,45]]}
    

    然后,你只保留该列并打印前五行,以验证请求是否符合预期。请注意,数据是否为我们用来训练模型的数据并不重要。它甚至可以是随机记录。我们关心的仅仅是将要发出的请求数量,而不是推断结果的样子。

  2. 使用以下代码将新创建的数据集存储在工作区中:

    from azureml.core import Dataset
    dstore = ws.get_default_datastore()
    loan_req_ds = Dataset.Tabular.register_pandas_dataframe(
        dataframe=prof_df,
        target=(dstore,"/samples/loans-requests"),
        name="loans-requests",
        description="Sample requests for the loans model")
    

    上述代码将 DataFrame 注册为loans-requests数据集。数据存储在默认数据存储中的/samples/loans-requests目录下。loans_req_ds变量引用了新注册的tabular数据集。

  3. 现在你已经拥有了必要的数据,可以使用以下代码开始模型分析过程:

    profile = Model.profile(ws,
                  'chapter12-loan',
                  [model], inference_config,
                  input_dataset=loan_req_ds,
                  cpu=2, memory_in_gb=1)
    profile.wait_for_completion(True)
    print(profile.get_details())
    

    请注意,profile 方法需要在前一部分模型部署时使用的modelinference_config。此外,你还需要指定用于分析的 ACI 大小。在前面的代码中,你请求了 2 个 CPU 和 1 GB 的 RAM。分析可能需要较长时间,有时超过 20 分钟。分析完成后,你将查看结果,包括作为recommendedCpu的 1 个 CPU 和作为recommendedMemoryInGB值的 0.5 GB RAM。

    重要说明

    模型分析的名称在工作区内应是唯一的。如果你在不更改名称的情况下重新运行步骤 3的代码,将会发生错误。

在后台,执行了一个名为ModelProfile的实验,它会部署一个带有模型的 ACI 服务。服务启动并运行后,过程会发送你在loan_req_ds数据集中指定的 500 个请求,并记录模型的响应时间,同时监控已部署容器实例的 CPU 和内存使用情况。根据这些统计数据,AzureML 可以建议你为实时端点配置的推荐 CPU 和内存。

在下一部分,你将使用这些值来部署 ACI 服务。随后,你将探讨如何在部署后监控其性能,并使用Application Insights记录传入的数据。

使用 Application Insights 进行监控

正如你在第二章中学到的,部署 Azure 机器学习工作区资源,当你部署 AzureML 工作区时,会在同一资源组中部署一个名为packtlearningm<random_number>的应用程序洞察账户。这个 Azure 资源使你能够监控应用程序的性能。特别是对于像你正在部署的实时端点这样的 Web 应用程序,应用程序洞察可以让你监控请求和响应时间、端点的失败率、代码中可能引发的任何异常,甚至是你希望从代码库中输出的日志痕迹。

在前面的理解模型部署选项部分中,你创建了一个包含几个print语句的score.py文件。这些信息被写入端点的控制台中,可以通过调用service.get_logs()方法或者导航到部署日志标签页来查看,如图 12.10所示:

图 12.10 – 容器实例控制台中记录的模型路径和传入的原始数据

图 12.10 – 容器实例控制台中记录的模型路径和传入的原始数据

这种方法的问题在于日志不会持久化。如果你重新部署容器实例,日志将会丢失。而且,如果你部署了多个模型,你将需要一个集中式的地方来监控它们。应用程序洞察为你的解决方案带来了这些及更多的好处。

返回你的chapter12.ipynb笔记本,重新部署 ACI 容器并为其启用应用程序洞察。在一个新的单元格中,添加以下代码:

from azureml.core.webservice import AciWebservice
deployment_config = AciWebservice.deploy_configuration(
   cpu_cores=1, memory_gb=0.5, enable_app_insights= True)
service = Model.deploy(ws, "aci-loans", [model], inference_config, deployment_config)
service.wait_for_deployment(show_output=True) 

注意,你正在使用在分析模型资源需求部分中推荐的1个 CPU 核心和0.5GB 的内存。另外,注意你正在通过传递enable_app_insights=True参数来在部署配置中启用应用程序洞察。如果你已经部署了服务并希望启用应用程序洞察,你可以使用以下代码更新其配置:

service.update(enable_app_insights=True)

让我们向服务发送几个请求,以便更好地理解应用程序洞察能为你做些什么。在一个新的单元格中,添加以下代码:

import json
input_payload = json.dumps({'data': [[2000, 2, 45], [2000, 9, 45]]})
for x in range(10):
   print(service.run(input_payload))

这段代码向服务发送了10个相同的请求,一个接一个地生成一些人工流量,这些流量应该会被记录在应用程序洞察中。找到指向 Azure 门户并直接进入应用程序洞察资源的 URL 的最简单方法是访问端点的信息页面,如图 12.11所示:

图 12.11 – 与你的 AzureML 工作区关联的应用程序洞察 URL

图 12.11 – 与你的 AzureML 工作区关联的应用程序洞察 URL

请注意,这个应用程序洞察 URL链接并不是针对aci-loans部署的特定链接。这个链接对于你所有的实时端点都是相同的,允许你集中监控所有的实时端点。点击这个链接将带你进入应用程序洞察,如图 12.12所示:

图 12.12 – 应用程序洞察显示你用最后一段代码发送的 10 个请求

图 12.12 – 应用程序洞察显示你用最后一段代码发送的 10 个请求

在此仪表板上,你可以点击图表并深入查看信号详情;或者你可以查看控制台中应用程序写入的所有追踪。要查看它们,请导航到监视 | 日志,点击追踪,选择你想调查的时间范围,然后点击运行按钮。你应该能在结果中看到所有STDOUT消息,并可以深入查看详细信息,如图 12.13所示:

图 12.13 – 阅读你的模型实时端点发出的所有追踪应用程序洞察中的端点

图 12.13 – 阅读你模型实时端点在应用程序洞察中发出的所有追踪

你可以在日志部分使用一种强大的类似 SQL 的语言——Kusto,来创建复杂的查询。你甚至可以根据这些查询创建自动化警报,例如,当过去 30 分钟内你的贷款拒绝次数超过 100 次时,系统会通知你。

重要提示

应用程序洞察支持每次最多 64 KB 的小负载日志。如果你计划记录超过 64 KB 的数据,例如,一个包含超过 64 KB 数据的小批量输入,你应该考虑使用 AzureML SDK 中的DataCollector类。该类允许你将数据直接记录到存储帐户中;但是,只有在 AKS 中部署时,才可使用此类。

在进入下一部分之前,请不要忘记删除已部署的服务,以防止 ACI 服务产生意外的费用。你可以在工作室体验中的资产 | 端点列表中删除该服务,或者通过以下代码行删除服务:

service.delete()

在本节中,你学习了如何在将实时端点部署到生产环境后进行监控。在图 12.12中,你可能注意到有几个swagger文件。在下一部分中,你将学习如何修复那些失败的请求,并实现与希望消费你模型结果的第三方应用程序的丰富集成。

与第三方应用程序集成

到目前为止,你已经部署了一个接受数组数组作为输入的 Web 服务。这是一个晦涩的输入,你需要向任何想要使用你实时端点的人解释它。在第五章《让机器进行模型训练》中,你了解了可以用来生成代码以自动消费你的端点的swagger文件。为了生成这样的文件,你可以使用开源的inference-schema包,并用元数据装饰你的代码,从而驱动swagger.json文件的生成。

为了使你的模型更容易被第三方应用程序消费,你应该接受以下有效负载:

{"data":[{"income": 2000, "credit_cards": 2, "age": 45}]}

在这里,你需要创建一个新的评分文件版本。与其克隆并编辑现有的评分文件,不如直接从 GitHub 页面下载修改后的score_v2.py版本,正如技术要求部分所提到的那样。在Notebooks部分,右键点击位于script文件夹中的score.py文件,选择Duplicate命令,复制该文件,如图 12.14所示:

图 12.14 – 创建入口脚本的 v2 文件

图 12.14 – 创建入口脚本的 v2 文件

图 12.14 – 创建入口脚本的 v2 文件

将克隆文件命名为score_v2.py,并修改代码,使其如下所示:

import os
import joblib
from inference_schema.schema_decorators import input_schema, output_schema
import pandas as pd
from inference_schema.parameter_types.pandas_parameter_type import PandasParameterType
import numpy as np
from inference_schema.parameter_types.numpy_parameter_type import NumpyParameterType

在脚本文件的开始部分,你导入了额外的辅助类,这些类稍后会在代码中使用。请注意,你不再需要json模块:

def init():
    global model
    model_path = os.path.join(os.getenv(\
"AZUREML_MODEL_DIR"), "model/model.joblib")
    model = joblib.load(model_path)

你不会修改init方法:

data_sample = pd.DataFrame(
    {
        "income": pd.Series([2000.0], dtype="float64"),
        "credit_cards": pd.Series([1], dtype="int"),
        "age": pd.Series([25], dtype="int")
    }
)
output_sample = np.array([0])

在前面的代码块中,你创建了一个pandas DataFrame,它将作为传入请求的data属性中包含的对象的示例。这个data_sample对象有一个income特征,它是float64类型,以及credit_cardsage特征,它们是整数类型。类似地,对于输出,你将output_sample定义为一个 NumPy 数组或数值。你可以在以下代码块的装饰器中使用data_sampleoutput_sample对象:

@input_schema("data", PandasParameterType(data_sample))
@output_schema(NumpyParameterType(output_sample))
def run(data):
    try:
        result = model.predict(data)
        return result.tolist()
    except Exception as e:
        error = str(e)
        return error

在这里,你使用data_sample对象和@input_schema装饰器。此外,你使用PandasParameterType,这表示紧随其后的名为pandas DataFrame的参数遵循由data_sample示例定义的模式。你使用@output_schema装饰器指定你的服务返回一个 NumPy 数组作为输出,类似于output_sample。一旦你配置了这些模式,你会注意到在run方法中不需要再反序列化传入的有效负载。data对象已经是一个反序列化后的pandas DataFrame

如果你想处理二进制文件而不是表格数据,例如处理图像,你可以使用@rawhttp指令,它会将原始的 HTTP 请求传递给你的run方法。使用纯 HTTP 请求可以给你更大的灵活性,包括设置响应头;这是配置诸如跨域资源共享CORS)等安全功能时所必需的。你可以在本章的进一步阅读部分找到更多关于这些高级场景的资源。

现在你已经准备好score_v2.py脚本文件的代码,你需要发布实时端点。要为新的评分功能创建实时端点,请在笔记本中的一个单元格内添加以下代码:

from azureml.core.model import InferenceConfig
from azureml.core.webservice import AciWebservice
myEnv.Python.conda_dependencies.add_pip_package("inference_schema[pandas-support]>=1.1.0")
inference_config = InferenceConfig(source_directory= "./script", entry_script='score_v2.py', environment=myEnv)
deployment_config = AciWebservice.deploy_configuration( cpu_cores=1, memory_gb=0.5)
service = Model.deploy(ws, "aci-loans", [model], inference_config, deployment_config)
service.wait_for_deployment(show_output=True)

在前面的代码中,你将inference_schema pip 包附加到你在理解模型部署选项部分中定义的myEnv依赖项中。请注意,你安装该包时使用了pandas-support扩展,这会包括pandas包。你的score_v2.py文件依赖的numpy依赖项会由 pip 自动安装,因为它是pandas包的依赖项。

接下来,你需要指定使用score_v2.py入口脚本并部署新服务。新服务将提供一个swagger.json文件,供第三方应用程序(如 Power BI)读取并自动了解如何调用你的模型。你可以在端点页面上获取指向该文件的 Swagger URI,如图 12.11所示。在端点页面上,你应该注意到测试选项卡已增强,指导你提供调用模型所需的字段。在代码方面,你可以使用以下负载调用模型:

import json
service = ws.webservices['aci-loans']
input_payload = json.dumps({"data":[
    {"income": 2000,"credit_cards": 2,"age": 45},
    {"income": 2000, "credit_cards": 9,"age": 45}
]})
print(service.run(input_payload))
input_payload = json.dumps({'data': [
    [2000, 2, 45], [2000, 9, 45]
]})
print(service.run(input_payload))

在进入下一节之前,确保使用以下代码删除你刚刚部署的 ACI 服务:

service.delete()

到目前为止,你一直在部署能够通过 REST API 处理临时推理请求的实时推理端点。在下一节中,你将学习如何部署一个批量推理管道,它能够使用ParallelRunStep并行处理大数据。

创建批量推理管道

第十一章《使用管道》中,你学会了如何创建多个步骤的管道并进行编排。这些管道可以通过 REST API 进行调用,类似于你在上一节中创建的实时端点。一个关键的区别是,在实时端点中,基础设施是持续开启的,等待请求到达,而在发布的管道中,集群仅在管道被触发后才会启动。

您可以使用这些管道来协调位于数据集中的数据的批处理推理。例如,假设您刚刚训练了本章中使用的loans模型。您希望对所有待处理的贷款请求运行该模型,并存储结果;这是为了便于您实施一个电子邮件营销活动,针对那些可能会被拒绝贷款的客户。最简单的方法是创建一个单独的PythonScriptStep,按顺序处理每条记录并将结果存储在输出文件夹中,正如您在第十一章中学到的那样,工作与管道。但是,您也可以将数据集拆分为多个批次,然后让它们在您的集群中每个节点内部的多个进程中并行处理,如图 12.15所示:

图 12.15 – 通过将大数据集拆分成较小的批次并并行处理它们来进行并行处理批次并行处理

图 12.15 – 通过将大数据集拆分成较小的批次并并行处理它们来进行并行处理

在本节中,您将创建一个批处理处理管道,该管道将使用您在本章中训练的chapter12-loans模型进行推理。您已经有一个名为loans的数据集,但它太小,无法展示ParallelRunStep如何通过并行化推理来加速处理。您将通过重复复制相同的 DataFrame 生成一个新的数据集,大小是原来的 1,024 倍。然后,您将创建一个类似于在第十一章中创建的管道,工作与管道。这一次,您将使用ParallelRunConfigParallelRunStep类来并行化数据集的处理。配置类需要一个入口脚本,类似于您在上一节中看到的入口脚本。此外,您还需要定义以下两个方法:

  • init(): 此方法加载模型并为即将到来的批次准备处理过程。此方法不期望有任何输出。

  • run(mini_batch): 此方法执行实际的数据处理。此方法将被多次调用,每次传递不同的mini_batch参数。您必须返回一个数组,其中包含每个成功处理的项目的行。例如,如果mini_batch参数包含 100 行,而您返回了 98 项数据,则表示您未能处理其中 2 条记录。如果您处理的是TabularDataset,则mini_batch参数可以是一个pandas DataFrame,如果您处理的是FileDataset,则可以是包含您需要处理的文件路径的数组。

导航到您的chapter12.ipynb笔记本,并执行以下步骤:

  1. 从获取对工作区、数据集和您将用于管道的计算集群的引用开始:

    from azureml.core import Workspace
    ws = Workspace.from_config()
    loans_ds = ws.datasets['loans']
    compute_target = ws.compute_targets['cpu-sm-cluster']
    

    代码应该是自解释的,因为您已经在第十一章《与管道一起工作》中使用过它。

  2. 基于loans数据集创建一个新的、更大的数据集:

    from azureml.core import Dataset
    loans_df = loans_ds.drop_columns('approved_loan') \  
                       .to_pandas_dataframe()
    for x in range(10):
        loans_df = loans_df.append(loans_df)
    dstore = ws.get_default_datastore()
    pending_loans_ds =\
    Dataset.Tabular.register_pandas_dataframe(
        dataframe=loans_df,
        target=(dstore,"/samples/pending-loans"),
        name="pending-loans",
        description="Pending loans to be processed")
    

    在前面的代码中,您正在将loansDataFrame加载到内存中,但不包含approved_loan列。这个数据集只有 500 行。然后,您将数据集追加到自身 10 次。这将创建一个包含 512,000 行的更大数据集,您将其注册为pending-loans

  3. 现在,是时候创建处理该数据集的脚本了。在chapter12文件夹中,添加一个pipeline_step文件夹,然后添加一个名为tabular_batch.py的文件,内容如下:

    from azureml.core import Model
    import joblib
    def init():
        global model
        model_path = Model.get_model_path("chapter12-loans")
        model = joblib.load(model_path)
    def run(mini_batch):
        print(mini_batch.info())
        mini_batch["approved"] = model.predict(mini_batch)
        return mini_batch.values.tolist()
    

    这个脚本有两个方法,如前所述。在init方法中,您使用Model类的get_model_path方法来获取您至今使用的模型的路径。从脚本的角度来看,模型将存储在脚本运行的同一台计算机的文件夹中。然后,您使用joblib将模型加载到名为modelglobal变量中。在run方法中,您打印传入 DataFrame 的大小,然后创建一个名为approved的新列,存储所有模型推断的结果。您返回一个包含每行处理记录的四元素数组的列表,类似于以下记录:

    [7298, 2, 35, 1]
    [4698, 7, 70, 0]
    

    如果您处理的是FileDataset而不是本节中处理的TabularDataset,那么相应的file_batch.py文件会如下所示:

    def init():
        print('Load model here')
    def run(mini_batch):
        output = []
        for file_path in mini_batch:
            output.append([file_path, 0])
        return output
    

    您像往常一样在init方法中加载模型,例如一个用于实现图像分类的神经网络。在run方法中,mini_batch参数是一个包含您需要处理的文件路径的数组。您可以遍历这些文件并使用模型进行推断。作为输出,您返回文件名和模型的结果,示例如下:

    ['/path/sample_cat.jpg', 0]
    ['/path/sample_dog.jpg', 1]
    

    步骤 5中,您将观察到,这些结果将聚合成一个在ParallelRunConfig中定义的单一文件。

  4. 您需要创建一个环境来执行管道步骤。将以下代码添加到一个单元格中:

    from azureml.core import Environment
    from azureml.core.conda_dependencies import CondaDependencies 
    import sklearn
    pEnv= Environment(name="sklearn-parallel")
    pEnv.Python.conda_dependencies = CondaDependencies()
    pEnv.Python.conda_dependencies.add_conda_package(f"scikit-learn=={sklearn.__version__}")
    pEnv.Python.conda_dependencies.add_pip_package("azureml-core")
    pEnv.Python.conda_dependencies.add_pip_package("azureml-dataset-runtime[pandas,fuse]")
    

    您需要安装scikit-learn的 conda 包,就像之前一样。为了使ParallelRunConfig正常工作,您还需要包括azureml-coreazureml-dataset-runtime[pandas,fuse]pip包。

  5. 接下来,创建ParallelRunConfig类,配置如何拆分工作负载以及使用哪个脚本进行数据处理。将以下代码添加到新的笔记本单元中:

    from azureml.pipeline.steps import ParallelRunConfig
    parallel_run_config = ParallelRunConfig(
        source_directory='pipeline_step',
        entry_script='tabular_batch.py',
        mini_batch_size='100Kb',
        error_threshold=-1,
        output_action='append_row',
        append_row_file_name="loans_outputs.txt",
        environment=pEnv,
        compute_target=compute_target, 
        node_count=1,
        process_count_per_node=2
    )
    

    在这里,您将运行位于pipeline_step文件夹中的tabular_batch.py脚本。您将把数据集拆分成大约 100 KB 的小批次。如果处理的是FileDataset,则需要指定每个批次中包含的文件数量。这里,error_threshold指定在处理数据时应该忽略的记录或文件失败的数量。-1表示您可以接受任何数量的处理错误。output_action参数接受append_row值或summary_only值。使用append_row值,您可以要求将所有run方法调用的输出附加到一个名为parallel_run_step.txt的单一输出文件中,除非通过append_row_file_name参数覆盖该文件名,正如前面的示例所演示的那样。由于记录是并行处理的,因此文件中的记录顺序无法保证。通常,您会返回客户 ID 或贷款申请 ID,以及模型的推断结果。通过该 ID,您可以将原始记录与模型的预测结果关联。在当前示例中,我们没有任何 ID;因此,我们返回整个行,就像在步骤 3中的tabular_batch.py脚本一样。

    接下来,您需要指定执行此流水线步骤的环境和集群。最后,您需要指定此流水线步骤将在单个节点上运行,并且每个参与节点将启动两个进程。如果使用两个节点,则会有四个进程并行运行。在当前示例中,两个并行进程足以在几分钟内完成处理。

    如果您的处理脚本需要超过 60 秒来处理您指定的mini_batch_size参数,您可以通过设置run_invocation_timeout参数来增加超时值。

  6. 下一步,您将定义之前指定的append_row_file_name的输出位置:

    from azureml.data import OutputFileDatasetConfig
    datastore = ws.get_default_datastore()
    step_output = OutputFileDatasetConfig(
        name= "results_store",
        destination=(datastore, '/inferences/loans/'))
    

    您将把该聚合文件存储在默认数据存储区下的/inferences/loans/文件夹中。

  7. 现在是时候创建流水线的第一个也是唯一的步骤——ParallelRunStep

    from azureml.pipeline.steps import ParallelRunStep
    parallel_step = ParallelRunStep(
        name='chapter12-parallel-loans',
        inputs=[pending_loans_ds.as_named_input('loans')],
        output=step_output,
        parallel_run_config=parallel_run_config,
        allow_reuse=False
    )
    

    将此步骤命名为chapter12-parallel-loans,并传递您在步骤 2中注册的pending_loans_ds数据集。输出存储在您在步骤 6中创建的OutputFileDatasetConfig中。指定此步骤不应被重用(allow_reuse);这允许您多次触发流水线,每次都获取数据集中的最新数据以及最新注册的模型。

  8. 使用以下代码创建并执行流水线:

    from azureml.core import Experiment
    from azureml.pipeline.core import Pipeline
    pipeline = Pipeline(workspace=ws, steps=[parallel_step])
    pipeline_run = Experiment(ws, 'chapter12-parallel-run').submit(pipeline)
    
  9. 您可以使用以下代码通过RunDetails小部件查看执行日志:

    from azureml.widgets import RunDetails
    RunDetails(pipeline_run).show()
    

    或者,您可以使用以下代码等待执行完成:

    pipeline_run.wait_for_completion(show_output=True)
    
  10. 从那时起,你可以根据第十一章使用管道,发布甚至安排流水线。

您可以访问 AzureML 工作室中的管道,观察它生成的输出和日志,如图 12.16所示。请注意,您将找到一个单节点和两个进程。每个进程都有多个run方法调用。每次调用run方法时,都会传入一个占用 117.3 KB 内存的 DataFrame,这接近您在步骤 5中请求的 100 KB:

图 12.16 – 并行执行日志显示 mini_batch DataFrame 信息

图 12.16 – 并行执行日志显示 mini_batch DataFrame 信息

在这一节中,您学习了如何创建一个可以并行处理大量数据的批处理流水线。这些是您在考试中需要了解的操作选项,涵盖实时和批处理模式。

摘要

在本章中,您探索了在本书中训练的机器学习模型的各种使用方式。您可以进行实时推断,也可以以经济高效的方式批处理大量记录。您开始注册用于推断的模型。从那里,您可以为测试部署 ACI 中的实时端点,或者为需要高可用性和自动扩展的生产工作负载部署到 AKS 中。您探索了如何配置您的模型以确定托管实时端点所需的推荐容器大小。接着,您发现了应用程序洞察,它允许您监视生产端点并识别潜在的生产问题。通过应用程序洞察,您注意到您生成的实时端点未公开一个swagger.json文件,这是第三方应用程序(如 Power BI)自动消费您的端点所需的。您修改了评分函数,以包含有关您的模型输入和输出的元数据,从而完成了本章的实时推断部分。

然后,您转向批处理推断部分,您在那里编写了一个可以并行处理 50 万条记录的流水线,仅用几分钟。将此并行化与低优先级计算结合使用时,处理更大数据量时能实现很大的成本节省。

恭喜!您已完成发现 AzureML 工作区基本功能的旅程。现在,您可以在工作区中进行机器学习实验,并可以根据适合解决业务问题的选项将生成的模型进行操作化。掌握了这些知识,您应该能够以优异的成绩通过DP-100考试,在 Azure 上设计和实施数据科学解决方案

问题

在每一章中,您将找到一系列问题来验证您对已讨论主题的理解:

  1. 您想要部署一个实时端点,处理来自一个在线博彩网站的交易。该网站的流量在比赛期间会有激增,夜间则非常低。您应该使用以下哪个计算目标?

    a. ACI

    b. 计算实例

    c. 计算集群

    d. AKS

  2. 您想要监控部署在 AKS 中的实时端点,并确定服务的平均响应时间。您应该使用哪个监控解决方案?

    a. ACI

    b. Azure 容器注册表

    c. 应用程序洞察

  3. 您有一个计算机视觉模型,并且想要并行处理 100 张图片。您编写了一个包含并行步骤的管道,您希望每次处理 10 张图片。您应该设置以下哪个 ParallelRunConfig 参数?

    a. mini_batch_size=10

    b. error_threshold=10

    c. node_count=10

    d. process_count_per_node=10

进一步阅读

本节提供了一些有用的网络资源列表,帮助您增强对 AzureML SDK 及本章中使用的各种代码片段的了解:

Packt.com

订阅我们的在线数字图书馆,全面访问超过 7,000 本书籍和视频,以及领先的行业工具,帮助你规划个人发展并推进职业生涯。欲了解更多信息,请访问我们的网站。

第十三章:为什么要订阅?

  • 通过来自超过 4,000 名行业专家的实用电子书和视频,减少学习时间,增加编码时间。

  • 通过专为你定制的 Skill Plans 提升你的学习。

  • 每月获得一本免费的电子书或视频。

  • 可完全搜索,轻松访问重要信息。

  • 复制并粘贴、打印和收藏内容。

你知道 Packt 提供所有出版书籍的电子书版本吗?PDF 和 ePub 格式的文件可用。你可以在packt.com升级到电子书版本,作为印刷版书籍的客户,你可以享受电子书版本的折扣。更多详情请通过 customercare@packtpub.com 联系我们。

www.packt.com,你还可以阅读一系列免费的技术文章,注册各种免费的电子通讯,并获得 Packt 图书和电子书的独家折扣和优惠。

你可能会喜欢的其他书籍。

如果你喜欢这本书,可能会对 Packt 的其他书籍感兴趣:

使用 Microsoft Azure 进行云分析

包括 Altaiar、Jack Lee 和 Michael Peña。

ISBN:9781839216404

  • 探索现代数据仓库和数据管道的概念。

  • 在应用云分析解决方案时,了解不同的设计考虑因素。

  • 设计一个端到端的云分析管道。

  • 区分结构化数据、半结构化数据和非结构化数据。

  • 为你的数据分析解决方案选择一个基于云的服务。

使用 Azure 服务来获取、存储和分析任何规模的数据

使用 Azure 数据服务进行云规模分析

Patrik Borosch。

ISBN:9781800562936

  • 使用 Azure 服务实施数据治理。

  • 在 Azure 门户中使用集成监控,并将 Azure Data Lake Storage 集成到 Azure Monitor 中。

  • 探索无服务器功能,进行临时数据发现、逻辑数据仓储和数据清洗。

  • 使用 Synapse Analytics 和 Spark 池实施网络连接。

  • 使用 Databricks 集群创建并运行 Spark 作业。

  • 使用 Azure Functions(Azure 上的无服务器运行时环境)实现流式处理。

  • 探索 Azure 中的预定义机器学习服务,并在你的应用中使用它们。

Packt 正在寻找像你这样的作者。

如果您有兴趣成为 Packt 的作者,请访问authors.packtpub.com并立即申请。我们已与成千上万的开发人员和技术专业人员合作,就像您一样,帮助他们与全球技术社区分享见解。您可以进行一般申请,申请我们正在招聘作者的特定热门主题,或提交您自己的想法。

分享您的想法

现在您已经完成了Azure 数据科学家认证指南,我们很乐意听取您的想法!如果您从亚马逊购买了这本书,请点击此处直接转到亚马逊评论页面并分享您的反馈或在购买网站上留下评论。

您的评论对我们和技术社区至关重要,将帮助我们确保我们提供卓越质量的内容。

posted @ 2025-07-19 15:45  绝不原创的飞龙  阅读(40)  评论(0)    收藏  举报