一、机器学习的四个分支
1.监督学习
监督学习是目前最常见的机器学习类型。给定一组样本(通常由人工标注),它可以学会将输入数据映射到已知目标[也叫标注(annotation)]。
主要包括分类和回归,同时包含几个其他部分
序列生成(sequence generation 。给定一张图像,预测描述图像的文字。序列生成有时可以被重新表示为一系列分类问题,比如反复预测序列中的单词或标记。
语法树预测(syntax tree prediction)。给定一个句子,预测其分解生成的语法树
目标检测 (obiect detection)。给定一张图像,在图中特定目标的周围画一个边界框。这个问题也可以表示为分类问题(给定多个候选边界框,对每个框内的目标进行分类)或分类与回归联合问题(用向量回归来预测边界框的坐标)。
图像分割(imagesegmentation)。给定一张图像,在特定物体上画一个像素级的掩模(mask)。
2.无监督学习
无监督学习是指在没有目标的情况下寻找输入数据的有趣变换,其目的在于数据可视化、数据压缩、数据去噪或更好地理解数据中的相关性。无监督学习是数据分析的必备技能,在解决监督学习问题之前,为了更好地了解数据集,它通常是一个必要步骤。降维 (dimensionalityreduction)和聚类(clustering)都是众所周知的无监督学习方法。
3.自监督学习
自监督学习是监督学习的一个特例,它与众不同,值得单独归为一类。自监督学习是没有人工标注的标签的监督学习,你可以将它看作没有人类参与的监督学习。标签仍然存在(因为总要有什么东西来监督学习过程 ),但它们是从输入数据中生成的,通常是使用启发式算法生成的。
4.强化学习
强化学习一直以来被人们所忽视,但最近随着 Google 的 DeepMind 公司将其成功应用于学习玩Atari游戏(以及后来学习下围棋并达到最高水平),机器学习的这一分支开始受到大量关注在强化学习中,智能体(agent)接收有关其环境的信息,并学会选择使某种奖励最大化的行动。例如,神经网络会“观察”视频游戏的屏幕并输出游戏操作,目的是尽可能得高分,这种神经网络可以通过强化学习来训练。
二、评估机器学习模型
机器学习的目的是得到可以泛化(generalize)的模型,即在前所未见的数据上表现很好的模型,而过拟合则是核心难点。
1.训练集、验证集、测试集
在于开发模型时总是需要调节模型配置,比如选择层数或每层大小[这叫作模型的超参数(hyperparameter),以便与模型参数(即权重)区分开]。这个调节过程需要使用模型在验证数据上的性能作为反馈信号。这个调节过程本质上就是一种学习:在某个参数空间中寻找良好的模型配置。因此,如果基于模型在验证集上的性能来调节模型配置,会很快导致模型在验证集上过拟合,即使你并没有在验证集上直接训练模型也会如此。
造成这一现象的关键在于信息泄露 (informationleak。每次基于模型在验证集上的性能来调节模型超参数,都会有一些关于验证数据的信息泄露到模型中。如果对每个参数只调节一次那么泄露的信息很少,验证集仍然可以可靠地评估模型。但如果你多次重复这一过程(运行一次实验,在验证集上评估,然后据此修改模型 ),那么将会有越来越多的关于验证集的信息泄露到模型中。
最后,你得到的模型在验证集上的性能非常好(人为造成的),因为这正是你优化的目的你关心的是模型在全新数据上的性能,而不是在验证数据上的性能,因此你需要使用一个完全不同的、前所未见的数据集来评估模型,它就是测试集。你的模型一定不能读取与测试集有关的任何信息,既使间接读取也不行。如果基于测试集性能来调节模型,那么对泛化能力的衡量是不准确的。
2.三种经典的评估方法
(1)简单的留出验证
留出一定比例的数据作为测试集。在剩余的数据上训练模型,然后在测试集上评估模型。如前所述,为了防止信息泄露,你不能基于测试集来调节模型,所以还应该保留一个验证集
示意图如下
这是最简单的评估方法,但有一个缺点:如果可用的数据很少,那么可能验证集和测试集包含的样本就太少,从而无法在统计学上代表数据。这个问题很容易发现:如果在划分数据前进行不同的随机打乱,最终得到的模型性能差别很大,那么就存在这个问题。接下来会介绍K折验证与重复的K折验证,它们是解决这一问题的两种方法。
(2)K折验证
K折验证 (K-fold validation)将数据划分为大小相同的K个分区。对于每个分区 i,在剩余的 K-1个分区上训练模型,然后在分区上评估模型。最终分数等于个分数的平均值。对于不同的训练集 -测试集划分,如果模型性能的变化很大,那么这种方法很有用。与留出验证样,这种方法也需要独立的验证集进行模型校正。
(3)带有打乱数据的K折验证
如果可用的数据相对较少,而又需要尽可能精确地评估模型,那么可以选择带有打乱数据的重复K折验证(iterated K-fold validation with shuffling)。具体做法是多次使用K折验证,在每次将数据划分为K个分区之前都先将数据打乱。最终分数是每次K折验证分数的平均值。注意,这种方法一共要训练和评估 PxK个模型(P是重复次数),计算代价很大。
3.注意事项
数据代表性(data representativeness)。你希望训练集和测试集都能够代表当前数据。例如,你想要对数字图像进行分类,而图像样本是按类别排序的,如果你将前 80% 作为训练集,剩余 20%作为测试集,那么会导致训练集中只包含类别 0~7,而测试集中只包含类别8~9。这个错误看起来很可笑,却很常见。因此,在将数据划分为训练集和测试集之前,通常应该随机打乱数据。
时间箭头(the arrowoftime)。如果想要根据过去预测未来(比如明天的天气、股票走势等),那么在划分数据前你不应该随机打乱数据,因为这么做会造成时间泄露(temporalleak):你的模型将在未来数据上得到有效训练。在这种情况下,你应该始终确保测试集中所有数据的时间都晚于训练集数据。
数据冗余(redundancy in your data)。如果数据中的某些数据点出现了两次(这在现实中的数据里十分常见),那么打乱数据并划分成训练集和验证集会导致训练集和验证集之间的数据冗余。从效果上来看,你是在部分训练数据上评估模型,这是极其糟糕的!定要确保训练集和验证集之间没有交集。
三、数据预处理、特征工程和特征学习
1.神经网络的数据预处理
数据预处理的目的是使原始数据更适于用神经网络处理,包括向量化、标准化、处理缺失值和特征提取。
(1)向量化
神经网络的所有输入和目标都必须是浮点数张量(在特定情况下可以是整数张量)。无论处理什么数据(声音、图像还是文本 ),都必须首先将其转换为张量,这一步叫作数据向量化data vectorization)。例如,在前面两个文本分类的例子中,开始时文本都表示为整数列表(代表单词序列),然后我们用one-hot 编码将其转换为 float32格式的张量。在手写数字分类和预测房价的例子中,数据已经是向量形式,所以可以跳过这一步。
(2)值标准化
在手写数字分类的例子中,开始时图像数据被编码为0~255范围内的整数,表示灰度值。将这一数据输人网络之前,你需要将其转换为 foat32格式并除以255,这样就得到0~1范围内的浮点数。
一般来说,将取值相对较大的数据(比如多位整数,比网络权重的初始值大很多)或异质数据(heterogeneous data,比如数据的一个特征在0~1范围内,另一个特征在 100200 范围内)输入到神经网络中是不安全的。这么做可能导致较大的梯度更新,进而导致网络无法收敛。为了让网络的学习变得更容易,输入数据应该具有以下特征:
取值较小:大部分值都应该在0~1 范围内。
同质性(homogenous):所有特征的取值都应该在大致相同的范围内。
此外,下面这种更严格的标准化方法也很常见,而且很有用,虽然不一定总是必需的(例如对于数字分类问题就不需要这么做)。
将每个特征分别标准化,使其平均值为 0
将每个特征分别标准化,使其标准差为 1。
(3)处理缺失值
数据中有时可能会有缺失值。例如在房价的例子中,第一个特征(数据中索引编号为0的列)是人均犯罪率。如果不是所有样本都具有这个特征的话,怎么办?那样训练数据或测试数据将会有缺失值。
一般来说,对于神经网络,将缺失值设置为0是安全的,只要 0不是一个有意义的值。网络能够从数据中学到0意味着缺失数据,并且会忽略这个值。
注意,如果测试数据中可能有缺失值,而网络是在没有缺失值的数据上训练的,那么网络不可能学会忽略缺失值。在这种情况下,应该人为生成一些有缺失项的训练样本:多次复制一些训练样本,然后删除测试数据中可能缺失的某些特征。
2.特征工程
特征工程(featureengineering)是指将数据输入模型之前,利用你自己关于数据和机器学习算法(这里指神经网络)的知识对数据进行硬编码的变换(不是模型学到的),以改善模型的效果。多数情况下,一个机器学习模型无法从完全任意的数据中进行学习。呈现给模型的数据应该便于模型进行学习。
良好的特征仍然可以让你用更少的资源更优雅地解决问题。例如,使用卷积神经网络来读取钟面上的时间是非常可笑的。
良好的特征可以让你用更少的数据解决问题。深度学习模型自主学习特征的能力依赖于大量的训练数据。如果只有很少的样本,那么特征的信息价值就变得非常重要。
四、过拟合和欠拟合
在上一章的三个例子(预测电影评论、主题分类和房价回归) 中,模型在留出验证数据上的性能总是在几轮后达到最高点,然后开始下降。也就是说,模型很快就在训练数据上开始过拟合。过拟合存在于所有机器学习问题中。学会如何处理过拟合对掌握机器学习至关重要
机器学习的根本问题是优化和泛化之间的对立。优化(optimization)是指调节模型以在训练数据上得到最佳性能(即机器学习中的学习),而泛化(generalization)是指训练好的模型在前所未见的数据上的性能好坏。机器学习的目的当然是得到良好的泛化,但你无法控制泛化只能基于训练数据调节模型。
训练开始时,优化和泛化是相关的:训练数据上的损失越小,测试数据上的损失也越小。这时的模型是欠拟合(underfit)的,即仍有改进的空间,网络还没有对训练数据中所有相关模式建模。但在训练数据上迭代一定次数之后,泛化不再提高,验证指标先是不变,然后开始变差即模型开始过拟合。这时模型开始学习仅和训练数据有关的模式,但这种模式对新数据来说是错误的或无关紧要的。
为了防止模型从训练数据中学到错误或无关紧要的模式,最优解决方法是获取更多的训练数据。模型的训练数据越多,泛化能力自然也越好。如果无法获取更多数据,次优解决方法是调节模型允许存储的信息量,或对模型允许存储的信息加以约束。如果一个网络只能记住几个模式,那么优化过程会迫使模型集中学习最重要的模式,这样更可能得到良好的泛化。这种降低过拟合的方法叫作正则化 (regularization)。我们先介绍几种最常见的正则化方法然后将其应用于实践中,以改进 3.4 节的电影分类模型
1.减少网络大小
防止过拟合的最简单的方法就是减小模型大小,即减少模型中可学习参数的个数(这由层数和每层的单元个数决定 )。在深度学习中,模型中可学习参数的个数通常被称为模型的容量capacity)。直观上来看,参数更多的模型拥有更大的记忆容量(memorization capacity),因此能够在训练样本和目标之间轻松地学会完美的字典式映射,这种映射没有任何泛化能力。
深度学习模型通常都很擅长拟合训练数据,但真正的挑战在于泛化,而不是拟合。
要找到合适的模型大小,一般的工作流程是开始时选择相对较少的层和参数,然后逐渐增加层的大小或增加新层,直到这种增加对验证损失的影响变得很小。
2.添加权重正则化
奥卡姆剃刀原理:如果一件事情有两种解释,那么最可能正确的解释就是最简单的那个,即假设更少的那个。这个原理也适用于神经网络学到的模型:给定一些训练数据和一种网络架构,很多组权重值(即很多模型)都可以解释这些数据。简单模型比复杂模型更不容易过拟合。
L1正则化(Llregularization ):添加的成本与权重系数的绝对值[权重的 L1范数(norm)]成正比。
L2正则化(L2regularization )添加的成本与权重系数的平方(权重的L2范数)成正比神经网络的L2正则化也叫权重衰减(weight decay)。不要被不同的名称搞混,权重衰减与L2正则化在数学上是完全相同的。
3.添加dropout正则化
dropout 是神经网络最有效也最常用的正则化方法之一,它是由多伦多大学的 Geofirey Hinton和他的学生开发的。对某一层使用 dropout,就是在训练过程中随机将该层的一些输出特征舍弃(设置为0)。假设在训练过程中,某一层对给定输入样本的返回值应该是向量 [0.2,0.,1.3,0.8,1.1]。使用dropout后,这个向量会有几个随机的元素变成0,比如[0,0.51.3,0,1.1]。dropout 比率(dropout rate) 是被设为0的特征所占的比例,通常在0.2~05范围内。测试时没有单元被舍弃,而该层的输出值需要按 dropout 比率缩小,因为这时比训练时有更多的单元被激活,需要加以平衡。
防止神经网络过拟合的常用方法包括:
获取更多的训练数据
减小网络容量
添加权重正则化
添加dropout
五、机器学习的通用流程
1.定义问题,收集数据集
2.选择衡量成功的指标
3.确定评估方法
4.准备数据
5.开发比基准好的模型
其中有三个重要参数
最后一层的激活
损失函数
优化配置