1.2 从标记数据中学习
机器学习的算法是多种多样的,我们也将在本书中学习许多机器学习算法。许多算法在概念上是很简单的(尽管它们本身的数学或编程基础可能很复杂),例如,假设我们想通过一组数据点找到最佳直线,如图1.5所示。
图1.5 给定一组数据点,我们可以想象一个直线算法,它通过这些点来计算出最佳直线
从概念上讲,我们可以想象一种算法,它可以仅用几个数字来表示任意直线,在给定输入数据点的情况下,它会用一些公式来计算出这些数字。这是一种常见的算法,它通过深入、仔细的分析来找到解决问题的最佳方法,然后将这一方法在执行该分析的程序中实现,这是许多机器学习算法使用的策略。
相比之下,许多深度学习算法使用的策略就不那么为人所熟知了,它们需要慢慢地从例子中学习,每次学习一点点,而后一遍又一遍地学习。每当程序看到要学习的新数据,它就会调节自己的参数,最终找到一组参数值——这组参数值便可以很好地帮助我们计算出我们想要的东西。虽然我们仍在执行一个算法,但它比用于拟合直线的算法更开放。这里运用到的思想是指:我们不知道如何直接计算出正确的答案,于是搭建了一个系统,这个系统可以自己搞明白如何去做。我们之所以要分析和编程,是为了创建一种能够自行求解出属于它自己的答案的算法,而不是去实现一个能够直接产生答案的已知的过程。
如果这听起来很疯狂,那就是它本身真的很疯狂,以这种方式找到它们自己的答案的程序,是深度学习算法取得巨大成功的关键。
在接下来的几节中,我们会进一步研究这种技术,去了解它,但它可能并不像传统的机器学习算法那样为我们所熟悉。最终,我们希望你可以用它来完成一些任务,例如,向系统展示一张照片,然后由系统返回其中每个人的名字。
这是一项艰巨的任务,所以让我们从一些比较简单的事情开始,来看看几个学习的示例。
1.2.1 一种学习策略
现在,让我们来思考一种对于教学生而言糟糕的方式,如图1.6所示。对于大多数学生来说,这并不是实际的教育方式,但这是我们教计算机的方式之一。
图1.6 这是一种很糟糕的育人方式。首先,让学生背诵一组事例,然后测试每个学生的背诵情况,之后测试他们没有接触过的其他事例。虽然学生并没有接触过这些事例,但是如果他们能够较好地理解第一组事例,那么就能推导出新给出的事例。如果学生在测试中取得了好成绩(尤其是第二门),那么他就毕业了;否则,就会再次重复这个循环,重新背诵相同的事例
在这种情景下(希望是虚构的),老师会站在教室前面,重复叙述一系列学生应该记住的事例,之后每个星期五下午学生们都要接受两次测试,第一次测试是根据这些特定的事例对他们进行盘问,以测试他们的记忆力;而第二个测试会在第一次测试之后马上进行,会问一些学生以前从未见过的新问题,以测试他们对事例的整体理解。当然,如果他们只收到一些事例,那么任何人都不太可能“理解”这些事例,这也是这种方式糟糕的原因之一。
如果一个学生在第二次测试中表现出色,那么老师就会宣布他已经学会了这门课,之后他就可以顺利毕业了。
如果一个学生在第二次测试中表现得不好,那么下个星期他将再次重复同样的过程:老师以完全相同的方式讲述同一个事例,然后还是通过第一次测试来衡量学生的记忆力,再通过第二次新的测试来衡量他们的理解或概括能力。每个学生都在重复这个过程,直到他们在第二次测试中表现得足够好,才可以毕业。
对于学生来说,这种教育方式是糟糕的,但这确实是一种非常好的教计算机学习的方式。
在本书中,我们将看到许多其他的教计算机学习的方式,但是现在让我们先来深入了解一下这种方式。我们将看到,与大多数人不同的是,每当计算机接触完全相同的信息,它都会学到一点点新的东西。
1.2.2 一种计算机化的学习策略
从收集我们要教的知识开始:我们需要收集尽可能多的数据。每一项观测数据(如某一特定时刻的天气)称为一个样本(sample);构成观测数据的名称(如温度、风速、湿度等)称为它的特征(feature)[Bishop06],每个被命名的测量数据或特征都有一个关联的值,通常被存储为一个数字。
在为计算机准备数据的过程中,我们需要将每个样本(即每个数据片段,其中的每个特征都被赋予一个值)都交给人类专家,由人类专家检查其特征并为该样本注明一个标签(label)。例如,如果样本是一张照片,那么标签可能是照片中人的名字、照片中所显示的动物的类型、照片中的交通是否顺畅或拥堵等。
以测量山上的天气为例,专家的意见用0~100分表示,它的含义是专家多大程度上认为“这一天的天气有利于徒步旅行”,如图1.7所示。
图1.7 我们从一组样本或数据项目开始对数据集进行标记,每个样本都由描述它的特征列表组成,我们将这个数据集交给一位人类专家,由他逐一检查每个样本的特征,并为该样本注明一个标签
我们通常会取一些带标签的样本并暂时把它们放在一边,并将在不久后用到它们。
一旦有了带标签的数据,我们就可以把它交给计算机,之后就可以让计算机找到一种方法来为每个输入匹配正确的标签。我们并没有告诉计算机如何去完成这个动作,而是给了它一个具有大量可调参数(甚至数百万个参数)的算法。不同的学习类型会使用不同的算法,本书的大部分内容都是致力于对它们的研究以及讲述如何更好地使用它们。一旦选择了一个算法,我们就需要通过它来运行一个输入,从而产生一个输出。这是计算机的预测(prediction),表达了计算机认为该样本是属于哪个专家标签。
当计算机的预测与专家标记的标签相符时,我们什么也不会做,但一旦计算机出错,我们就要求计算机修改它所使用的算法的内部参数,这样当我们再次给它相同的数据时,计算机就更有可能预测出正确的答案。
这基本上是一个反复试验的过程,计算机尽其所能给我们正确的答案,如果失败了,它就会遵循一个程序来改变和改进。
一旦做出预测,我们就只检查计算机的预测与专家的标签是否匹配,如果它们不匹配,我们会计算出一个误差(error),也称为代价(cost)或损失。这是一个数值,用于告知算法离正确结果还有多远。该系统会根据其内部参数的当前值、专家的预测结果(当前已知)以及自己的错误预测来调整算法中的参数,以便在再次看到这个样本时预测正确的标签。稍后我们将仔细研究这些步骤是如何执行的。图1.8展示了上述过程。
图1.8 训练(或者说学习)过程的一个步骤。我们将样本的特征和标签分开,根据这些特征,算法会预测出一个标签。我们将预测值与实际标签进行比较,如果预测标签与我们想要的标签相匹配,我们就什么都不做,否则我们将告知算法去进行修改或更新,这样它就不会再犯同样的错误
我们是通过“(1)分析训练数据集中的样本;(2)针对不正确的预测对算法进行更新”来训练(train)系统学习如何预测数据的标签。
我们将在后续章节中详细讨论应该如何进行选择不同的算法和更新步骤,目前我们需要知道的是,每个算法都是通过改变内部参数来实现预测的。每当出现错误预测,算法就可以对其参数进行修改,但是如果修改太多,就会使得其他的预测变得糟糕起来。同样,算法也可以只对其参数做很微小的修改,但是这样会导致学习速度较其他情况而言更加缓慢。我们必须通过对每种类型的算法和我们所训练的每一个数据集进行反复的试验,才能够在这两种极端之间找到正确的平衡。我们把对参数更新的多少称为学习率(learning rate),所以,如果我们采用一个小的学习率,就代表着谨慎和缓慢;而如果采用一个大的学习率,就可以加速整个过程,但也有可能会适得其反。
打个比方,假设我们在沙漠里,需要用金属探测器找到一个埋在地下的装满东西的金属盒子。我们会把金属探测器晃来晃去,如果在某个方向得到响应,我们就会朝那个方向移动。如果我们谨慎一点,每次只走出一小步,就不会错过盒子或是丢掉信号;但如果我们非常激进,每次迈出一大步,这样我们就能更快地接近盒子。也许我们可以从大步前进开始,但是随着离盒子越来越近,我们可以逐渐减小步幅,这也就是我们通常所说的“调整学习率”,通过调整学习率使得在刚开始训练时对系统的改动很大,但是会逐渐减小这个改动。
有一种有趣的方法可以让计算机在只记住输入而不进行学习的情况下获得高分,为了得到一个完美的分数,算法所要做的就是记住专家为每个样本标记的标签,然后返回那个标签的值。换句话说,它不需要学习如何计算出给定样本的标签值,而只需要在表中查找到正确的答案即可,在前文假设的学习场景中,这就相当于学生在考试中记住了问题的答案。
有时这会是一个很好的策略,稍后我们就会看到,有些非常有效的算法就遵循了这种方法。但是,如果是让计算机从数据中学到一些东西,并能够将所学推广应用到新的数据中,那么使用这种有趣的方法往往会适得其反。这种方法的问题在于:系统已经记住了样本的标签,导致所有训练工作都不会给我们带来任何新的东西,且由于计算机对数据本身一无所知,而只是从表中得到答案,计算机就不知道如何为它从未见过和记住的新数据创建预测。整个问题的关键在于我们需要让系统能够预测以前从未见过的新数据的标签,这样就可以放心地将其应用于会不断出现新数据的实际场景中。
如果算法在训练集上执行得足够好,但是在新数据上执行得很差,就说该算法的泛化能力很差。现在让我们看看如何提高算法的泛化能力,或者说如何学习数据,使得它能够准确地预测新数据的标签。
1.2.3 泛化
我们会用到1.2.2节中提到的暂时搁置的标记数据。
我们通过向系统展示它之前从未见过的样本来评估系统对所学知识的泛化(generalization),而这个测试集(test set)也会向我们展示系统对于新数据的表现。
现在,让我们来看一个分类器(classifier),这种系统会为每个样本分配一个标签(标签描述了该样本所属的类别或类)。假如输入是一首歌,那么它的标签可能是歌曲的流派(如摇滚或古典);假如输入是动物的照片,那么它的标签可能是照片上的动物(如老虎或大象)。而在运行的例子中,我们便可以将每天预期的“徒步旅行经历”归为三类:糟糕的、好的和很棒的。
我们会要求计算机预测测试集中每个样本的标签(这些都是计算机以前从未见过的样本),然后比较计算机的预测和专家的标签,如图1.9所示。
图1.9 评估一个分类器的整个过程
在图1.9中,我们将测试数据拆分为特征和标签两部分,该算法为每一组特征分配(或者说预测)了一个标签。然后,我们通过比较预测的标签和真实标签来衡量预测的准确率。如果预测结果足够好,那么我们就可以部署系统;如果预测结果不够好,那么我们需要继续进行训练。注意,与训练不同,这个过程中没有反馈和学习,在我们回到明确的训练模式之前,算法并不会改变它的参数,不管它的预测结果是否准确。
如果计算机对这些全新的样本(对于算法来说是全新的)的预测与专家分配的标签不匹配,那么我们将回到图1.8所示的训练步骤。我们会把原先训练集中的每个样本再给计算机看一遍,让它继续进行学习。注意,给出的是相同的样本,所以我们要求计算机从相同的数据中反复学习。通常来说,我们会对数据进行洗牌,使得样本以不同的顺序到达,但是不会给算法任何新的信息。
然后我们会要求算法再次预测测试集的标签,如果表现不够好,我们将再次返回原先的训练集进行学习,然后再测试,一遍又一遍地重复这个过程。这个过程往往需要重复几百次,我们一遍又一遍地向计算机展示同样的数据,而计算机每次都多学习一点。
正如我们之前所说的那样,这是一种糟糕的教学方式,但是计算机不会因为一遍又一遍地看到相同的数据而感到厌烦或焦躁,它只是不断学习它能够学会的东西,之后在每次学习中一点点地变得更好。
1.2.4 让我们仔细看看学习过程
我们通常认为数据中存在某种关联,毕竟如果它是完全随机的,我们就不会试图从中提取信息。在1.2.3节中,我们所希望的过程是通过向计算机一遍又一遍地展示训练集,来让它从每个样本中一点点地学习,最终该算法将找到样本特征与专家分配的标签之间的关联,进而可以将这种关联应用到测试集的新数据上。如果预测大部分是正确的,那么我们就说它具有很高的准确率,或者说泛化误差(generalization error)很小。
但是,如果计算机一直无法改进它对测试集标签的预测,我们就会因无法取得进展而停止训练。通常我们会修改算法以期待得到更好的表现,再重新进行训练。但这只是我们的一种期待,无法保证对于每一组数据都有一个成功的学习算法,即便有,我们也无法确保一定能够找到它。好消息是,即使不通过数学运算,计算机也可以通过实践找到泛化的方法,有时得到的结果比人类专家做得更好。
其中一个导致算法学习失败的可能原因是:它没有足够的计算资源来找到样本与其标签之间的关联。有时,我们会认为计算机创建了一种底层数据的模型(model)。例如,如果我们测量到在每天的前3个小时里温度会上升,计算机就可能会构建一个“模型”来表达早上温度会上升。这只是数据的一个版本,就像小型塑料版本的跑车或飞机是大型交通工具的一种“模型”一样,我们在前文中所看到的分类器就是一种模型。
在计算机中,模型是由软件结构和它所用的参数值组成的,更庞大的程序和参数集可以引导模型从数据中学习更多内容,这时我们就说它有更大的容量(capacity),或者说表征能力。我们可以把这看作算法能够学习的东西的深度和广度,而更大的容量使我们有更大的能力从已知的数据中发现含义。
打个比方,假设我们在为一名汽车经销商工作,就需要为所销售的汽车写广告,而市场部已经给了我们一份可以用于描述汽车的“得到认可的词汇”,工作一段时间后,我们也许就可以学会用这个模型(得到认可的词汇表)来完美地描述每一辆车。
假设这时经销商买了一辆摩托车,那么我们现有的词汇(或者说现有的模型)就没有足够的“容量”来描述这个交通工具——我们的容量只能描述之前描述过的那些交通工具。我们并没有足够多的词汇量来指代有两个轮子而不是4个轮子的东西,我们可以竭尽所能,但是结果可能并不理想。如果我们可以使用更强大的、有更大容量的模型(也就是说,更多用于描述交通工具的词汇),就能做得更好。
但是更庞大的模型也意味着更多的工作量,正如我们将在后续章节中看到的那样:相比小一点的模型,更庞大的模型往往会产生更好的结果,但代价是耗费更多的计算时间和计算机内存。
算法中会随着时间的推移自主进行修改的值称为参数(parameter),同时学习算法也会受设定的值所控制(如学习率),这些设定的值称为超参数(hyper parameter)。
参数和超参数的区别在于:计算机会在学习过程中自主调整它自己的参数值,而超参数值则是在我们编写和运行程序时设定的。
当算法学得足够好,能够在测试集上执行得足够好,足以令人满意时,我们就可以将它部署(deploy)(或者说发布)。一旦用户提交了数据,系统就会返回它预测的标签。
这就是人脸图如何变成名字、声音如何变成文字以及对天气的监测如何变为预报的过程。
现在让我们回过头来宏观地看看整个机器学习领域。如果要对机器学习这一广阔且持续发展的领域进行调查,那么需要占用一整本书的篇幅(参见“参考资料”中的[Bishopo6]和[Goodfellow17])。接下来,我们介绍当今大多数学习工具的主要分类。在本书中,我们会反复提到这类算法。