多类是指输出不止有两个输出标签,需要对多个种类进行分类,即下图的情况。
对于多类中的激励的求法与逻辑回归不同,计算方法如下图:
代价函数如下图:
可以得出其代价函数与逻辑回归相似,代价函数与y的取值有关。同时当y一定时,值越大,其损失函数值越小。
采用最大回归模型,并将其放入神经网络输出层,具体如下图:
可以发现softmax的输出函数与逻辑回归的不同,softmax中与所有z都有关系。
下图是构建softmax神经网络的代码,主要分为三个步骤,首先是建立模型,接着定义代价函数和损失函数,最后是训练数据并得到最小的代价函数。
其中SparseCategoricalCrossentropy是稀疏范畴交叉熵函数,当然作者并不推荐使用上图的代码,在之后的学习中会了解到更加简洁的代码。
为了更好地理解这个改进算法,先看一个例子,如下图:
如果交给我们计算图中的值,得到的结果应该是相同的。但对于电脑计算则不一定,因此在计算中需要选择合适的办法。
张量流可以重新排列这个表达式中的项,并提出一个更精确的数值方法来计算这个损失函数。因此最初的过程明确地计算了a这个中间变量,但采用图中修改后的代码所指的表达式作为损失函数,给了张量流更多的灵活性,选择是否计算a,修改后的代码将输出层设置为只使用线性激活函数,所以张量流只会计算出z,这个代码的缺点是,它变得不清晰了,张量流的数值较少。
整个结构代码如上图,需要注意的是最后输出为z1到z10。
如果你把输出逻辑函数和损失函数结合起来,那对于逻辑回归,还需要改变代码获取输出值,并通过逻辑函数映射它,得到实际概率,具体如下图所示l:
还有一种不同的分类问题,称为多标签分类问题(multi-label classification)。例如在设置自动驾驶系统时,通过车前的情况,判断有没有汽车,公交和行人。
例如上图所看到的,判断不同的图片是否有汽车,公交和行人,将会获得一个三维向量结果。在这种情况下,应该如何构建神经网络呢?也许可以构建三个神经网络分别进行判断,但在实际中是不现实的,因此面对这种问题就需要构建一个多层分类的神经网络,即在输出层设置三个输出,如下图。
这样就可以通过一个神经网络区别这三者了。
事实证明,现有一些其他的优化算法来最小化成本函数,甚至比梯度下降更好;本节将研究一种算法,可以更快地训练神经网络。首先回顾一下梯度下降算法,当α较小时,你会发现梯度下降的每一步基本上是朝着同一个方向的,如果将α增大,下降的步伐就可以更大,正好Adam算法可以实现这个功能。
当α较大时,你会发现梯度下降的方向都在不断变化,如果将α减小,可以更好实现梯度下降,Adam算法也可以实现这个功能。
Adam:Adaptive Moment estimation(自适应矩估计);该算法在不同的下降阶段采用不同的学习率。当参数的沿着同一个方向下降时,会选择增加学习率,当参数下降的方向来回摆动,会选择减小学习率。实现代码如下:
#model
model = Sequential([
tf.keras.layers.Dense(units=25,activation='sigmoid')
tf.keras.layers.Dense(units=15,activation='sigmoid')
tf.keras.layers.Dense(units=10,activation='linear')
])
#compile
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True))
#fit
model.fit(X,Y,epochs=100)
和之前的代码相比,增加了一个优化算法,并设置了默认的初始学习率α=0.001。在实践中,该算法是一个比较常用的安全的算法,使用该算法还需要对学习率进行多次尝试。
之前所学的所有网络都是密集层类型,即每一层的神经元都是从前一层获得输入信息。现在还发现有一些其他类型的层也有其他属性,下面将列举不同类型的网络层。
卷积层(Convolution):
每一个神经元只能获得左侧图片的一部分信息,这样可以加快神经元的计算速度;只需要一层卷积层,需要的训练数据较少;也可以避免过度拟合。
通过心电图的例子来介绍卷积层,在第一层卷积层中,每个神经元只处理一部分数据,且每部分数据都相互有重叠,在第二层卷积层中也只处理第一层的部分激活值,激活值也都有重叠,最后的输出层则采用了sigmoid函数与之前的输出层相同。
假设你已经使用了线性回归来预测房价,且你已经获得了成本函数和正则化条件,但当你在训练这个模型时,发现它在预测中出现了一些错误,你接下来会怎么做,有以下选择方法:
1、获得更多训练数据;
2、尝试减少它的特征;
3、尝试获得额外的功能(找到房子的其他属性作为输入数据);
4、尝试增加特征多项式();
5、尝试减小λ;
6、尝试增加λ。
下面你将学习如何修改机器学习的模型,提高其算法性能。
例如之前谈到的房价预测模型,如下图:
虽然它的与训练集拟合地十分好,但对于预测新的价格就会产生较大的误差。因此需要一种方法来评估一个模型是否恰当。
有一种评估方法,便是将训练数据分成两部分,第一部分是训练集,第二部分是测试集,数量比例接近7:3。训练模型主要包括以下两步,首先使用训练集来训练模型参数并计算训练集的训练误差,再使用测试集来计算测试误差,评估模型的性能。
本节将使用一种技术自动为你的机器选择一个好的模型,当模型的参数w和b符合训练集,训练误差则不是一个很好的指标,由上一节知道指标可以更好地反应模型的性能。为了在不同的模型中选择合适的训练模型,需要进行以下的修改,即将数据集分成训练集(60%),交叉验证集(20%)和测试集(20%)三部分。
首先采用训练集计算不同模型的参数,接着计算在交叉验证集的,并选择交叉验证误差最小的模型,最后如果想了解选出的模型在新数据上的效果,可以用测试集进行验证。这种模型选择程序,也适用于其他类型的模型选择,例如神经网络体系。如果你正在安装一个手写数字识别模型,你有以下三个模型可以选择,也可以先通过训练集获得参数,再通过交叉验证集计算,并选择交叉验证误差最小的模型,最后用测试集来估计选择的神经网络的性能。
左图图有较高的偏差,右图有较高的方差,中间的图像则比较合适下图展示了多项式次数和训练集误差,交叉验证误差的关系
值得注意的是,有时也会遇到高偏差和高方差同时存在的情况,这个时候和都比较大,且还远大于。
这一节主要介绍如何选择正则化中的参数λ的值。当λ取一个较大值,例如λ=10000时,将会得到下方的左图,近似于一条平行于x轴的直线,因为λ特别大时,为了确保代价函数取得最小值,参数w的也会变得特别小,并且这个模型就含有较高的偏差;当λ取一个较小值,例如λ=0时,将会得到下方的右图,即没有进行正则化的模型,这个模型的交叉验证误差特别大并含有较大的方差;当选择适当的λ值,该模型的 和都比较小。
下图为λ和训练集误差,交叉验证误差的关系:
可以看出只有选择合适的λ才能得到相对较小 的 和 。
如何判断模型是否有较高的偏差和方差,将用语音识别的例子来讲解。通过用不同方法计算语音识别的能力,发现观察训练误差是否远高于人类的表现水平,更能说明系统性能的好坏。
建立一个基准水平,可以更好地评价系统性能,当基准水平误差与训练集误差较大,则该系统存在较大的偏差;当 和 二者的差距较大,说明该系统还存在方差较大的问题;当基准水平误差与训练集误差较大且 和 二者的差距较大时,说明系统存在较大的偏差和方差。
学习曲线可以帮助你了解训练数量和模型训练情况的关系,也可以从学习曲线看出模型是否存在高偏差或者高方差,下图为学习曲线。
根据上图可以看出当训练集数量不断增加,的值不断减小,的值不断增加,最后两者趋近相同。由此看出二者接近时,就是合适的训练集数量。
当存在高方差时,训练数据较小时, 和 二者差距较大,当不断增加训练数量,二者差距减小,且接近基准水平。
当存在高偏差时,不断增加训练数量, 和 二者的值会相近,且基准水平相差较大。在这种情况下增加训练数量不能提高模型性能。
当算法中有很高的方差时,可以采用以下方法改善:1、增加训练集数量,2、减少特征数量,3、增加λ的值。
当算法中有很高的偏差时,可以采用以下方法改善:1、增加特征数量,2、增加额外的多项式特征3、减少λ的值。
在神经网络的选择中,也需要根据 和 两者的值,来设计更好的模型,如下图:
通过上图的方法可以获得性能更好的神经网络模型,正则化神经网络模型的搭建代码如下,即在每一层增加了参数λ的变化,通过选择合适的λ,得到合适的模型。
机器学习模型搭建的过程:首先需要选择构建的组成(模型,数据等);接着对模型进行训练;最后对模型的效果(偏差,误差和错误分析)进行诊断。如果需要构建更大的神经网络或修改正则化参数λ,可以重复上述过程。
接下来通过垃圾邮件分类的例子进行详细介绍,系统的输入为邮件中存在的特征,输出为判断其是否属于垃圾邮件,因为不可能识别邮件中的所有文字,因此选择了邮件中最常用的一万个单词作为特征,通过0和1表示是否存在该单词。
模型搭建好后,如何减少分类的错误,可以采取以下方法:
1、收集更多的数据
2、根据电子邮件路由进行判(例如邮件标题)
3、从邮件正文中定义更加复杂的功能(例如将discounting和discount归为一类)
4、设计监测拼写错误的算法
在上节垃圾邮件分类例子中,如何对其进行误差分析,就是本节的内容。在500个交叉验证集的测试中,出现了100个分类错误,接着就需要对这100个例子进行手动检查并根据共同特征再次进行分类。比如发现有21份都是药品类的邮件,再从这21份中进行分类,可以分为四类(包括故意拼写错误、不寻常的电子邮件路由、窃取密码和插入图像的垃圾邮件),拼写错误所占比例较小,因此在设计神经网络时可以重点关注其他三类特征。
当交叉验证集数量为5000时,可能就有1000个出现错误,全部手动检查工作量太大,这时会选择其中的100个进行手动检查,最好的情况是可以从这100个中分类出各种不同的错误。通过检查你可能会得到一些灵感,比如在某个方向选择更多的数据用于模型训练。误差分析与偏差和方差一样可以帮你改进模型。
有时获取更多各种各样的数据对模型能力的提高较为缓慢并且昂贵,相反通过误差分析找到的增加数据的途径可以获得较好的效果,接着可以在你想提升的方向增加训练数据。比如你想增加识别26个英文字母的能力,就需要增加字母的图像数据信息,例如:旋转后的字母A,不同大小的字母A 和镜像的字母A等。
接着还可以通过引入失真来增加数据,如下图
数据添加也可以用在语言识别中,除了原声外,可以在原声的基础上增加背景音或者噪音,合成后的声音作为添加的数据,这样也可以提高模型性能。
从上述两个例子可以发现,在添加数据时,可以选择给原有的数据添加噪音或者让其失真,不过需要注意的是,在数据中添加没有意义或随机噪音是没有帮助的。
最后还总结了两种不同的机器学习分类,如下图:
即传统的以模型为中心的方法,其工作重心为构造模型和选择算法;另一种为以数据为中心的方法,其工作重心为选择数据。
对于一个没有那么多数据的系统,迁移学习是一种很棒的技术,它允许使用不同任务的数据来帮助这个系统。
以下是迁移学习的工作原理:
例如需要搭建一个神经网络识别手写数字0-9,但没有足够的数据集,这个时候有大量识别其他物品的数据集,就可以先用这个大量的数据集去训练网络,并得到每一层的参数,并将输出层以外的结构作为需要搭建的网络结构。接下来有两种方法训练需要搭建的模型;第一种方法是只训练输出层;第二种是训练整个网络(输出层外的参数保持不变)。如果训练集数量特别少,则选择第一种方法更好,如果训练集数量相对多一点,则选择第二种方法更好。
接着通过进一步的学习,它可以成为一个更好的模型,主要分为两步:首先是在大数据集上进行第一次训练(监督预训练Supervised pretraining),接着在更小的数据集上进一步调整参数(微调Fine tuning)。第一部实际上已经有人完成了,我们可以直接在网络中下载一个神经网络,然后替换输出层,再进行训练和微调即可。
可以采用迁移学习的原因是,在前面几层的训练中,都有类似的地方。例如采用神经网络来检测图像,它的第一层可以学习检测图像中的边缘,第二层学会把边缘分组来检测角落,每一个神经元都已经学会检测到的物品的可视化,第三层就可能学会检测一些更复杂的形状(曲线或基础形状)。
总结一下迁移学习的步骤:
1、下载带有参数的神经网络,并在具有与应用程序相同输入类型(图像、音频、文字等)的大数据集上训练。
2、根据自己的数据调节优化网络,
第一步是确定项目的目的,第二步是收集相关数据,第三步是训练模型并对系统进行误差分析,并根据误差分析选择是否多收集一些数据,(这一步可能会重复多次,直到项目性能达标),第四步部署实施项目,并对项目进行监视和维护,(在工作发现其性能变差后,需要返回训练或者收集更多的数据集用于训练)。事实上用户使用该项目并产生的数据有助于提高项目的性能
例如在语言识别模型的部署中,首先需要将模型放置在推理服务器(inference server)中,通过手机应用程序收集语音并通过API调用将语音片段发送给服务器,通过模型得到文本输出并返回给手机应用程序。当然这个过程还需要软件工程师来帮忙,确保可靠和高效的预测,并实时监控系统和完成模型的更新。
本节主要讲述了在使用机器学习这个工具时,需要确保其工作是符合道德伦理的,不应当将其用于区别对待不同的人,当它出现区别对待的情况时,应当及时修正模型参数,避免产生偏见。
假设正在训练一个二元分类器,检测患者是否患有罕见疾病,假设你发现在测试集上存在百分之一的错误,但该罕见病的发病率只有0.5%。这时就不知道如何判断该分类器的性能,因此采用构造混淆矩阵的方法,在上面的轴线上写真正的结果(0或1),在垂直轴上写预测结果(0或1),并将交叉测试集的结果写在对应的正方形中。
可以通过精度和召回两个指标判断上述学习算法性能,精确度(precision)的定义是真正正数的数量除以被归类为正数的数量,召回(recall)定义为真正的正数除以实际的正数的数量。
高精度意味着,一个患者检测结果为阳性后,其患罕见病的概率就很大;高召回则是指所有患病的人中,被查出疾病的概率比较大。这两个数据是矛盾的,我们需要结合实际情况来权衡。当选择高精度时,判断是否患病的阈值会设置的偏大一些;当选择高召回时,判断是否患病的阈值会设置的偏小一些。因此衡量精度值和召回率后,还需要选择合适的阈值。
可以通过比较不同算法中精度值和召回率的调和平均数来来选择合适模型,调和平均数越大,算法性能相对更好。
15.1 决策树模型
为了更好的理解决策树,将通过猫的种类分类的例子进行介绍。有以下多个特征(耳朵的形状、脸的形状,是否有胡须),现在需要训练一个分类器来快速判断该动物是否是猫。
在这个例子中动物的特征就是输入值x,输出值为是否为猫,每一个特征都只有两种情况。可以将上图构成一个决策树。
上图中的矩形或者椭圆被称作树的一个节点,最上面的椭圆称为根节点(root node),所有椭圆被称为决策节点(decision nodes),最下面的长方形节点被称为叶子节点(leaf node)。
建立一个的决策树的过程:在给出的一个训练集中,首先需要决定选择哪个特征作为根节点,之后再选择决策树的左分支放置什么节点,通过左侧节点后,可以实现分辨猫的功能,则可以直接在左侧节点后设置叶子节点,右侧节点的设置方法与左侧相同。
在建立上图的决策树时,需要作出以下几个决定:
1、如何选择在每个节点上使用什么特性进行分割
选择某个特征实现纯度最大化(maximize purity )
2、多久停止分裂
①直到一个节点中全是猫或全不是猫;
②进一步分裂会超过树的最大深度(由决策树的一个参数决定,深度的定义为节点到根节点的距离);
③当纯度达到一定阈值;
④节点上的数量低于某个阈值。
是例子中猫的数量的占比,需要用熵(entropy)来测算一组例子中的杂质。
=1-,为例子中除了猫其他动物的占比,
熵函数的表达式为:
值得注意的是当=0时,该公式默认。
在搭建决策树时,选择哪一个特征作为根节点,就需要通过计算信息熵来进行判断。 为了使计算的信息熵更加准确,这里采用了计算加权平均信息熵的方法,并将H(0.5)减去加权值,得到信息熵,通过比较信息熵的大小,判断应该将耳朵形状作为根节点。
为左分支动物数占根节点总数的比值;
为根节点中被预测物(如例子中的猫)的数量占总数的比值;
通过比较信息熵大小,并选择信息熵最高的拆分方法。
以下是搭建决策树的总体过程:
1、从树根节点的所有训练示例开始,计算所有可能特性的信息增益,选择能获得最高信息的特征;
2、然后根据特性将数据集拆分为两个子集,并创建树的左、右分支,并将训练示例放在左、右分支上;
3、在树的左、右分支上重复分裂过程,直到达到停止标准(详见15.2)。
根据上图可以看到,在根节点下又创建了两个子决策树进行分类,这就是一个递归算法的例子。当你看到决策树的代码时,会看到递归算法的引用,在一些开放源代码库会有较好的默认最大深度参数可以使用,在构建更大的决策树时需要避免过度拟合的问题。
之前的例子中,每个特征都只包含两个不同的值,当特征包含超过两个值时,就需要用独热编码来解决。
如上图的例子,宠物耳朵的特征有三种情况(尖、椭圆、软),现在将耳朵特征变成三个不同的特征(是否有尖耳朵、是否有椭圆耳朵、是否有软耳朵),如下图
独热编码:当一个特征有k(k>2)个值时,创建k个不同的特征来替代原有特征,新创建的特征只有两个值(0或1)。
当把所有特征用0或1代替后,便可以将特征提供给神经网络或者逻辑回归,来尝试训练猫分类器。
当特征中包含连续值的特征时,可以修改决策树,使之不只是在离散值的特性中工作,如下图增加宠物的体重特征。
为了找到合适的体重值进行分类,先将宠物的体重和是否为猫绘制在下图的坐标轴上。
接着需要尝试选择不同的x值来计算信息熵,如果在体重特征中的最大信息熵大于其他所有特征的信息熵,就选择在体重特征上拆分该节点。
之前只讨论了决策树作为分类算法,它还可以作为回归算法。根据宠物的其他特征,来预测其体重。
可以采用方差来选择采用哪个特征进行分类,其计算方法与信息熵类似,得到结果即减少的方差,值越大,其回归性能越好。
使用单一决策树的缺点是其对数据中的微小变化较为敏感,当采用多个决策树可以有助于解决这个问题,构建多个决策树称树集成。
如上图所示,构建了多个决策树进行判断其是否为猫,汇总每个树的结果,根据是否为猫的结果数量判断得到结论。
为了建立多个决策树,需要采用放回抽样技术,抽样放回即在每次抽样后将样本放回总样本中,前一次抽样结果不会影响后一次抽样结果,在训练多个决策树可以采用放回抽样的方法生产训练集,如下图。
本节将讲述如何集成树,首先在训练集中通过放回抽样的方式抽取m个数据构成一个子集,并重复操作得到多个子集,用不同的子集训练不同的决策树,如下图。
假设共有n个可用的特征,需要从特征中选择k(k XGBoost是一种更加方便快速的集成决策树的算法,它的开源很容易实现,它的工作方法与随机森林算法有相似之处,不过在第一次训练后,除了从训练集随机抽取一部分数据外,还会从已经训练且出错的数据中抽取一部分(进行刻意练习)。 XGBoost的优势: 1、增强决策树的开源实现; 2、可以快速高效的实施; 3、有良好的拆分标准和停止分裂的标准; 4、内置正则化,可以防止过度拟合; 5、极具竞争力的机器学习算法。 XGBoost的实现比较复杂,因此许多实践者会使用开源库来实现。 决策树和神经网络的比较:17.4 XGBoost
17.5 什么时候选择决策树
决策树
神经网络
对结构化数据效果良好
适用于所有类型数据
不建议处理非结构化数据(图像、音频、文本)
速度较慢
速度较快
可以采用迁移学习
小的决策树是人为可以判断的
更容易组建更大的神经网络