直到最近,您在日常生活中可能与之交互的几乎每个计算机程序都被编码为一组严格的规则,精确指定了它应该如何运行。假设我们要编写一个应用程序来管理电子商务平台。在围着白板思考几个小时后,我们可能会确定一个可行解决方案的大致思路,例如:(i) 用户通过在 Web 浏览器或移动应用程序中运行的界面与应用程序交互;(ii) 我们的应用程序与商业级数据库引擎交互,以跟踪每个用户的状态并维护历史交易记录;(iii) 在我们应用程序的核心,业务逻辑(你可能会说,大脑) 我们的应用程序阐明了一组规则,将每一种可能的情况映射到我们的程序应该采取的相应行动。
为了构建我们应用程序的大脑,我们可能会枚举我们的程序应该处理的所有常见事件。例如,每当客户点击将商品添加到他们的购物车时,我们的程序就应该向购物车数据库表添加一个条目,将用户的 ID 与请求的产品 ID 相关联。然后我们可能会尝试遍历每一个可能的极端情况,测试我们的规则的适当性并进行任何必要的修改。如果用户使用空购物车开始购买会怎样?虽然很少有开发人员第一次就完全正确(可能需要进行一些测试才能解决问题),但在大多数情况下,我们可以编写此类程序并自信地启动它们见过真正的客户。我们通常在新情况下手动设计驱动功能产品和系统的自动化系统的能力是一项了不起的认知壮举。当您能够设计出有效的解决方案时 \(100\%\)当时,您通常不应该担心机器学习。
幸运的是,对于不断壮大的机器学习科学家群体来说,我们想要自动化的许多任务并不容易屈从于人类的聪明才智。想象一下,你认识的最聪明的人围坐在白板周围,但这一次你要解决以下问题之一:
-
编写一个程序,根据地理信息、卫星图像和过去天气的拖尾窗口预测明天的天气。
-
编写一个程序,接受一个以自由格式文本表达的事实型问题,并正确回答它。
-
编写一个程序,根据给定的图像识别图像中描绘的所有人,并在每个人周围画出轮廓。
-
编写一个程序,向用户展示他们可能会喜欢但在自然浏览过程中不太可能遇到的产品。
对于这些问题,即使是精英程序员也很难从头开始编写解决方案。原因可能各不相同。有时我们正在寻找的程序遵循一种随时间变化的模式,因此没有固定的正确答案!在这种情况下,任何成功的解决方案都必须优雅地适应不断变化的世界。在其他时候,关系(比如像素和抽象类别之间的关系)可能过于复杂,需要数千或数百万次计算并遵循未知的原则。在图像识别的情况下,执行任务所需的精确步骤超出了我们的意识理解,即使我们的潜意识认知过程毫不费力地执行任务。
机器学习是对可以从经验中学习的算法的研究。随着机器学习算法积累更多经验(通常以观察数据或与环境交互的形式),其性能会提高。将此与我们的确定性电子商务平台进行对比,无论积累多少经验,它都遵循相同的业务逻辑,直到开发人员自己学习并决定是时候更新软件了。在本书中,我们将向您介绍机器学习的基础知识,尤其是深度学习,这是一套强大的技术,可在计算机视觉、自然语言处理、医疗保健和基因组学等不同领域推动创新。
1.1. 一个激励人心的例子
在开始写作之前,本书的作者和许多工作人员一样,不得不喝下咖啡因。我们跳上车,开始开车。亚历克斯使用 iPhone 喊出“Hey Siri”,唤醒了手机的语音识别系统。然后Mu命令“去Blue Bottle咖啡店的方向”。手机很快就显示出他的命令抄录。它还认识到我们正在询问方向并启动了地图应用程序 (app) 来满足我们的请求。启动后,地图应用程序会识别出多条路线。在每条路线旁边,手机会显示预计的通行时间。虽然我们为了教学方便而编造了这个故事,但它表明,在短短几秒钟的时间里,我们与智能手机的日常互动可以涉及多种机器学习模型。
想象一下,只需编写一个程序来响应诸如“Alexa”、“OK Google”和“Hey Siri”之类的唤醒词。尝试自己在房间里用计算机和代码编辑器编写代码,如图1.1.1所示。你会如何根据第一性原理编写这样的程序?想一想……这个问题很难。每秒,麦克风将收集大约 44000 个样本。每个样本都是对声波振幅的测量。什么规则可以可靠地将一段原始音频映射到自信的预测 \(\{\text{yes}, \text{no}\}\)关于片段是否包含唤醒词?如果您被卡住了,请不要担心。我们也不知道如何从头开始编写这样的程序。这就是我们使用机器学习的原因。
这是诀窍。通常,即使我们不知道如何明确地告诉计算机如何将输入映射到输出,我们仍然能够自己完成认知壮举。换句话说,即使你不知道如何让计算机识别“Alexa”这个词,你自己也能识别它。有了这种能力,我们可以收集一个巨大的数据集,其中包含音频片段和相关标签的示例,指示哪些片段包含唤醒词。在机器学习的主流方法中,我们不会尝试设计一个明确识别唤醒词的系统。相反,我们定义了一个灵活的程序,其行为由许多参数决定. 然后我们使用数据集来确定可能的最佳参数值,即那些可以根据所选性能指标提高程序性能的参数值。
您可以将参数视为我们可以转动的旋钮,从而操纵程序的行为。固定参数,我们称程序为模型。我们仅通过操纵参数就可以生成的所有不同程序(输入-输出映射)的集合称为 模型族。而使用我们的数据集来选择参数的元程序称为学习算法。
在我们继续使用学习算法之前,我们必须精确定义问题,确定输入和输出的确切性质,并选择合适的模型系列。在这种情况下,我们的模型接收一段音频作为输入,然后模型生成一个选择\(\{\text{yes}, \text{no}\}\)作为 输出。如果一切按计划进行,模型对片段是否包含唤醒词的猜测通常是正确的。
如果我们选择正确的模型系列,应该有一个旋钮设置,这样模型每次听到“Alexa”这个词时都会发出“是”。因为唤醒词的确切选择是任意的,我们可能需要一个足够丰富的模型系列,通过旋钮的另一种设置,它可以仅在听到“Apricot”这个词时发出“是”。我们期望相同的模型系列应该适用于“Alexa”识别和“Apricot”识别,因为从直觉上看,它们似乎是相似的任务。然而,如果我们想要处理根本不同的输入或输出,比如我们想要从图像映射到字幕,或者从英文句子映射到中文句子,我们可能需要完全不同的模型系列。
您可能会猜到,如果我们只是随机设置所有旋钮,我们的模型不太可能识别“Alexa”、“Apricot”或任何其他英文单词。在机器学习中,学习是我们发现旋钮的正确设置的过程,通过该过程可以从我们的模型中强制执行所需的行为。换句话说,我们用数据训练我们的模型。如图 1.1.2所示,训练过程通常如下所示:
-
从一个随机初始化的模型开始,它不能做任何有用的事情。
-
抓取你的一些数据(例如,音频片段和相应的 \(\{\text{yes}, \text{no}\}\)标签)。
-
调整旋钮以使模型在这些示例中评估时表现更好。
-
重复步骤 2 和 3,直到模型很棒。
总而言之,我们不是编写唤醒词识别器的代码,而是编写一个可以学习识别唤醒词的程序,如果提供一个大型标记数据集的话。您可以将这种通过向程序展示数据集来确定程序行为的行为视为使用数据进行编程. 也就是说,我们可以通过为我们的机器学习系统提供许多猫和狗的例子来“编程”一个猫检测器。这样,检测器最终将学习如果它是猫则发出一个非常大的正数,如果它是狗则发出一个非常大的负数,如果不确定则发出接近于零的值。这仅仅触及了机器学习可以做什么的皮毛。我们稍后将更详细地解释深度学习,它只是解决机器学习问题的众多流行方法之一。
1.2. 关键部件
在我们的唤醒词示例中,我们描述了一个由音频片段和二进制标签组成的数据集,并且我们对如何训练模型来近似从片段到分类的映射给出了一个简单的概念。这类问题,我们尝试根据已知输入预测指定的未知标签,给定由标签已知的示例组成的数据集,称为 监督学习。这只是众多机器学习问题中的一种。在我们探索其他品种之前,我们想更清楚地了解一些核心组件,无论我们处理什么样的机器学习问题,这些核心组件都会跟随我们:
-
我们可以从中学习的数据。
-
如何转换数据的模型。
-
量化模型运行情况的目标函数。
-
调整模型参数以优化目标函数的算法。
1.2.1. 数据
不用说,没有数据就无法进行数据科学。我们可能会浪费数百页来思考数据到底是什么,但现在,我们将专注于我们将关注的数据集的关键属性。通常,我们关注示例的集合。为了有效地处理数据,我们通常需要提出合适的数字表示。每个示例(或数据点、数据实例、样本)通常由一组称为特征的属性(有时称为协变量或 输入),模型必须基于此做出预测。在监督学习问题中,我们的目标是预测一个特殊属性的值,称为标签(或目标),它不是模型输入的一部分。
如果我们处理的是图像数据,则每个示例都可能包含一张单独的照片(特征)和一个指示照片所属类别的数字(标签)。照片将以数字方式表示为三个数值网格,代表每个像素位置的红光、绿光和蓝光的亮度。例如,一个\(200\times 200\)彩色照片将包括\(200\times200\times3=120000\)数值。
或者,我们可以使用电子健康记录数据来处理预测给定患者在接下来 30 天内存活的可能性的任务。在这里,我们的特征可能包括一组现成的属性和经常记录的测量值,包括年龄、生命体征、合并症、当前药物治疗和最近的程序。可用于训练的标签将是一个二进制值,指示历史数据中的每个患者是否在 30 天窗口内存活。
在这种情况下,当每个示例都具有相同数量的数字特征时,我们说输入是固定长度的向量,我们将向量的(恒定)长度称为数据的维度。正如您想象的那样,固定长度的输入可能很方便,让我们不必担心那么复杂。但是,并非所有数据都可以轻松表示为固定长度向量。虽然我们可能期望显微镜图像来自标准设备,但我们不能期望从 Internet 中提取的图像都以相同的分辨率或形状显示。对于图像,我们可能会考虑将它们全部裁剪为标准尺寸,但该策略只能让我们走到这一步。我们冒着丢失裁剪部分信息的风险。此外,文本数据更顽固地抵制固定长度的表示。考虑在亚马逊、IMDb 和 TripAdvisor 等电子商务网站上留下的客户评论。有些很短:“它很臭!”。其他人漫不经心地寻找页面。与传统方法相比,深度学习的一大优势是现代模型可以相对优雅地处理变长数据。
通常,我们拥有的数据越多,我们的工作就越容易。当我们拥有更多数据时,我们可以训练更强大的模型,减少对先入为主的假设的依赖。从(相对)小数据到大数据的机制变化是现代深度学习成功的主要贡献者。为了说明这一点,深度学习中许多最令人兴奋的模型如果没有大型数据集就无法工作。其他一些在小数据领域工作,但并不比传统方法好。
最后,拥有大量数据并巧妙地处理数据是不够的。我们需要正确的数据。如果数据充满错误,或者如果所选特征不能预测感兴趣的目标数量,学习就会失败。陈词滥调很好地描述了这种情况:垃圾进,垃圾出. 此外,糟糕的预测性能并不是唯一的潜在后果。在机器学习的敏感应用中,例如预测性监管、简历筛选和用于贷款的风险模型,我们必须特别警惕垃圾数据的后果。一种常见的故障模式发生在训练数据中没有代表某些人群的数据集中。想象一下,在以前从未见过黑色皮肤的野外应用皮肤癌识别系统。当数据不仅不能充分代表某些群体而且反映了社会偏见时,也可能会失败。例如,如果过去的招聘决定被用来训练一个用于筛选简历的预测模型,那么机器学习模型可能会无意中捕捉到历史上的不公正现象并将其自动化。
1.2.2. 楷模
大多数机器学习都涉及在某种意义上转换数据。我们可能想要构建一个系统来摄取照片并预测笑脸。或者,我们可能想要获取一组传感器读数并预测读数的正常与异常程度。按 型号,我们表示用于摄取一种类型的数据并吐出可能不同类型的预测的计算机器。特别是,我们对可以从数据中估计的统计模型感兴趣。虽然简单的模型完全能够解决适当的简单问题,但我们在本书中关注的问题超出了经典方法的局限性。深度学习与经典方法的区别主要在于它关注的一组强大模型。这些模型由许多连续的数据转换组成,这些数据从上到下链接在一起,因此得名深度学习。在讨论深度模型的过程中,我们还将讨论一些更传统的方法。
1.2.3. 目标函数
早些时候,我们将机器学习介绍为从经验中学习。通过 在这里学习,我们的意思是随着时间的推移在某些任务上有所改进。但是谁能说什么是改进呢?您可能会想象我们可以提议更新我们的模型,而有些人可能不同意提议的更新是改进还是下降。
为了开发一个正式的学习机器数学系统,我们需要对我们的模型有多好(或多坏)有正式的衡量标准。在机器学习和更一般的优化中,我们称这些 为目标函数。按照惯例,我们通常将目标函数定义为越低越好。这只是一个惯例。您可以采用任何越高越好的函数,并通过翻转符号将其转换为质量相同但越低越好的新函数。因为越低越好,这些函数有时被称为损失函数。
当尝试预测数值时,最常见的损失函数是平方误差,即预测值与真实目标之间的差值的平方。对于分类,最常见的目标是最小化错误率,即我们的预测与基本事实不一致的示例部分。一些目标(例如,平方误差)易于优化,而其他目标(例如,错误率)由于不可微性或其他复杂性而难以直接优化。在这些情况下,通常会优化替代目标。
在优化过程中,我们将损失视为模型参数的函数,并将训练数据集视为常数。我们通过最小化由为训练收集的一些示例组成的集合所产生的损失来学习模型参数的最佳值。然而,在训练数据上做得很好并不能保证我们在看不见的数据上也会做得很好。因此,我们通常希望将可用数据分成两个部分:训练数据集(或训练集),用于学习模型参数;和测试数据集(或测试集), 用于评估。在一天结束时,我们通常会报告我们的模型在两个分区上的表现。您可以将培训绩效视为类似于学生在用于准备某些实际期末考试的练习考试中取得的分数。即使结果令人鼓舞,也不能保证在期末考试中取得成功。在学习过程中,学生可能会开始背诵练习题,看似掌握了主题,但在面对实际期末考试中以前没见过的问题时却步履蹒跚。当一个模型在训练集上表现良好但无法泛化到看不见的数据时,我们说它对训练数据过度拟合。
1.2.4. 优化算法
一旦我们获得了一些数据源和表示、模型和定义明确的目标函数,我们就需要一种能够搜索最佳参数以最小化损失函数的算法。流行的深度学习优化算法基于一种称为梯度下降的方法。简而言之,在每个步骤中,此方法都会检查每个参数,以查看如果您对该参数进行少量扰动,训练集损失将以何种方式移动。然后它在降低损失的方向上更新参数。
1.3. 机器学习问题的种类
我们激励示例中的唤醒词问题只是机器学习可以解决的众多问题之一。为了进一步激励读者并为我们提供一些贯穿全书的通用语言,我们现在提供机器学习问题公式的广泛概述。
1.3.1. 监督学习
监督学习描述的任务是给定一个包含特征和标签的数据集,并负责生成一个模型来预测给定输入特征的标签。每个特征-标签对称为一个示例。有时,当上下文清楚时,我们可以使用术语示例引用一组输入,即使相应的标签未知。监督发挥作用是因为为了选择参数,我们(监督者)为模型提供了一个由标记示例组成的数据集。在概率方面,我们通常对估计给定输入特征的标签的条件概率感兴趣。虽然它只是机器学习中的几种范式之一,但监督学习占机器学习在工业中的大部分成功应用。部分原因是,许多重要任务可以清晰地描述为在给定一组特定的可用数据的情况下估计未知事物的概率:
-
根据计算机断层扫描图像预测癌症与非癌症。
-
给出英语句子,预测正确的法语翻译。
-
根据本月的财务报告数据预测下个月的股票价格。
虽然所有监督学习问题都被简单描述“预测给定输入特征的标签”所捕获,但监督学习可以采取多种形式并需要大量建模决策,具体取决于(除其他考虑因素外)输入的类型、大小和数量和输出。例如,我们使用不同的模型来处理任意长度的序列和处理固定长度的向量表示。我们将在本书中深入探讨其中的许多问题。
非正式地,学习过程如下所示。首先,获取大量特征已知的示例,并从中随机选择一个子集,为每个示例获取真实标签。有时这些标签可能是已经收集到的可用数据(例如,患者是否在下一年内死亡?),而其他时候我们可能需要使用人工注释器来标记数据(例如,将图像分配给类别)。这些输入和相应的标签一起构成了训练集。我们将训练数据集输入监督学习算法,该算法将数据集作为输入并输出另一个函数:学习模型。最后,我们可以将以前看不见的输入提供给学习模型,使用其输出作为相应标签的预测。图 1.3.1。
1.3.1.1. 回归
也许最简单的监督学习任务就是回归。例如,考虑从房屋销售数据库中收集的一组数据。我们可以构建一个表,其中每一行对应不同的房子,每一列对应一些相关属性,例如房子的平方英尺、卧室数、浴室数和分钟数(步行) 到市中心。在这个数据集中,每个例子都是一个特定的房子,对应的特征向量是表格中的一行。如果你住在纽约或旧金山,而且你不是亚马逊、谷歌、微软或 Facebook 的首席执行官,那么你家的(平方英尺、卧室数量、浴室数量、步行距离)特征向量可能看起来像:\([600, 1, 1, 60]\). 然而,如果你住在匹兹堡,它可能看起来更像\([3000, 4, 3, 10]\). 像这样的固定长度特征向量对于大多数经典机器学习算法来说都是必不可少的。
使问题回归的实际上是目标的形式。假设您正在市场上购买新房。考虑到上述某些特征,您可能想要估算房屋的公平市场价值。这里的数据可能包括历史房屋清单,标签可能是观察到的销售价格。当标签采用任意数值(即使在某个区间内)时,我们称之为 回归问题。目标是生成一个模型,其预测非常接近实际标签值。
许多实际问题很容易描述为回归问题。预测用户对电影的评分可以被认为是一个回归问题,如果你在 2009 年设计了一个伟大的算法来完成这一壮举,你可能会赢得 100 万美元的 Netflix奖。预测患者住院时间的长短也是一个回归问题。一个好的经验法则是多少?或者有多少?问题应该建议回归,例如:
-
这个手术需要几个小时?
-
这个镇在接下来的六个小时内会有多少降雨量?
即使您以前从未接触过机器学习,您也可能非正式地解决过回归问题。想象一下,例如,您修理了下水道,而您的承包商花了 3 个小时从污水管道中清除垃圾。然后他寄给你一张 350 美元的账单。现在想象一下,您的朋友雇用了同一个承包商 2 小时,他收到了一张 250 美元的账单。如果随后有人问你对他们即将开出的清除垃圾发票的期望值是多少,你可能会做出一些合理的假设,比如工作更多的时间会花费更多的钱。您可能还假设有一些基本费用,然后承包商按小时收费。如果这些假设成立,那么根据这两个数据示例,您已经可以确定承包商的定价结构:每小时 100 美元外加 50 美元出现在你家。如果你遵循了这么多,那么你已经理解了线性回归背后的高级思想。
在这种情况下,我们可以生成与承包商价格完全匹配的参数。有时这是不可能的,例如,如果某些差异归因于除您的两个特征之外的几个因素。在这些情况下,我们将尝试学习最小化我们的预测与观察值之间的距离的模型。在我们的大部分章节中,我们将重点关注最小化平方误差损失函数。正如我们稍后将看到的,这种损失对应于我们的数据被高斯噪声破坏的假设。