您的位置:首页 > 其它

吴恩达《深度学习工程师》Part2.Week1 深度学习的实用层面

2018-02-21 01:28 363 查看
1.1 训练/开发/测试集

在构建一个机器学习模型时,需要将数据分配为训练(training)集、开发(development)集、测试集(test)集,合理的分配将会显著提高模型训练的效率。


图1 训练/开发/测试集分配

如图1所示,训练集用于开展对模型的训练,开发集用于选择最好的模型,当模型确定好以后,在测试集上来进行无偏评估。在机器学习时代,常见的数据划分做法是训练集70%测试集30%。如果没有明确设置验证集,也可以按照60/20/20%进行划分,以上做法针对的时数据集较小的情况,例如1万个数据左右。

针对大数据时代的深度学习,测试集和测试集比例会减小。例如有100万个数据的话,只需要拿出1万个(1%)数据作为验证集,1万个(1%)数据作为测试集。对于超高100万的数据集,验证集和测试集甚至可以更小(0.25%和0.25%)


图2 训练/测试集分布不匹配的情况

现在越来越多的情况是训练集和测试分布是不同的,例如检测图片中是否有猫的模型,训练集中的图片一般来自网页,都是高分辨率的清晰图片,而验证和测试集的图片大都是用户自己拍摄的低分辨率模糊图片。为了保证良好的预测效果,需要保证训练集和验证、测试集分布保持一致。

另外,如果不需要进行无偏测试的话,测试集也可以省去,即只划分训练集和验证集。

2.1 偏差/方差

偏差和方差时衡量一个模型预测效果好坏的重要指标。



图3 不同的偏差和方差情况

左图采用logistic回归分析预测的分类结果,该模型不能有效区分出不同类型,属于高偏差的情况。右图采用深层神经网络构建出了复杂的分类模型,虽然有效区分出了所有的不同类别,但是模型过于复杂,出现了过拟合(overfitting),属于高方差的情况。中图区分出了大部分的不同类别,虽然有个别值出现了错误分类,但总体分类准确度很高且模型较为简单,属于较优的模型。

下面以猫的分类模型为例进行说明。


图4 偏差和方差在猫分类模型中的表现

假设人眼的识别误差几乎达到0%

如果训练集误差为1%,验证集误差为11%,则是训练集过拟合(overfitting)的情况,属于高方差。

如果训练集误差为15%,验证集误差为16%,则是训练集欠拟合(underfitting)的情况,属于高偏差。

如果训练集误差为15%,验证集误差为30%,则是训练集欠拟合(underfitting)和过拟合(overfitting)同时存在的情况,高偏差和高方差并存。

如果训练集误差为0.5%,验证集误差为1%,则模型效果较好,属于低偏差和低方差。

注意,如果人眼的识别误差是15%的话,如果训练集误差为15%,验证集误差为16%,则认为模型表现是很优秀的,属于于低偏差和低方差的情况。

最后,图5说明了高方差和高偏差同时存在的情况。


图5 高方差和高偏差并存

分类曲线对整体的分类效果较弱,存在多个数据分类错误的情况,整体属于欠拟合,此外曲线中心部位较为复杂,对两个数据点进行了正确的分类,却出现了过拟合的情况。

1.3 机器学习基础

这节讲述了如何针对高偏差、高方差的情况对模型进行调试的策略。


图6 高偏差、高方差的模型调试策略

如果模型出现了高偏差(训练集上出现欠拟合),则可以增大网络规模,例如增加隐藏层层数、提高节点数目等来减小偏差,或者【训练时间延长、采用新型的网络架构(后面讲到的CNN,RNN等)】,【】中的方法可能有效也可能无效,需要实际地去尝试才知道。重复这些步骤,直到模型在训练集上能够达到很好的拟合效果。

将上面训练好的模型用于验证集时,可能会出现高方差(训练集过拟合)的情况,最好的解决方法是采用更多的数据,但是如果不能获得更多的数据的话,可以采用正则化的方法,减小过拟合的现象。

这里有两点需要注意:

1.高偏差和高方差是两种不同的情况,需要有针对性的选取模型的优化策略。

2.在机器学习的早期,有很多关于权衡偏差和方差策略的讨论,这是因为当时的一些策略只能单一的减小偏差却提高方差,或者减少方差提高偏差,很难实现两者的同时减小。在如今的深度学习和大数据时代,只要持续训练一个更大的网络,就能够减小偏差而不影响方差。喂给模型更多的数据,可以做到减小方差而不显著影响偏差。

1.4 正则化

当你的模型出现了过拟合,也就是方差过大的情况时,一个有效的方法时增大训练集的数据量,但是当没有更多的数据或者获取新的数据成本过高时,可以使用正则化(regularization)的方法。

以logistic回归为例,可以将代价函数加入一个正则化项。

J(w,b)=1m∑1m(y^[i]−y[i])+λ2m||w||22J(w,b)=1m∑1m(y^[i]−y[i])+λ2m||w||22

其中||w||22||w||22为ww的欧几里德范数:

||w||22=∑j=1nxw2j||w||22=∑j=1nxwj2

这种方法称为L2L2正则化。为什么不在代价函数中加入偏置bb的正则化项呢?因为ww包含了很多参数,这些参数已经可以描述过拟合的情况,这时bb可以省略掉。

还有一种方法是L1L1正则化:

λ2m∑1nx|w|=λ2m||w||1λ2m∑1nx|w|=λ2m||w||1

如果使用L1L1正则化,得到的ww将是稀疏的,也就是其中有很多0。

上面的λλ是正则化参数,通常使用验证集来调试λλ参数,这样可以把ww控制在一个较小的值,防止过拟合。

神经网络模型中的正则化如下:

J(w[1],b[1],w[L],b[L])=1m∑1m(y^[i]−y[i])+λ2m∑l=1L||w[l]||2J(w[1],b[1],w[L],b[L])=1m∑1m(y^[i]−y[i])+λ2m∑l=1L||w[l]||2

其中:

||w[l]||2=∑i=1l−1∑j=1l(w[l]ij)2||w[l]||2=∑i=1l−1∑j=1l(wij[l])2

为WW矩阵中每个ww的平方和,该矩阵范数称为frobenius 范数。

这样在进行权重更新时,除了原有的反向传播得到的dwdw外,还要加入正则化项的导数:

dw[l]=(FromBackPropagation)+λmw[l]dw[l]=(FromBackPropagation)+λmw[l]

w[l]:=w[l]−α⋅dw[l]w[l]:=w[l]−α⋅dw[l]

将dw[l]dw[l]代入w[l]w[l]得到:

w[l]=(1−αλm)w[l]−α⋅(FromBackPropagation)w[l]=(1−αλm)w[l]−α⋅(FromBackPropagation)

也就是w[l]w[l]变为一个小于1的值乘以w[l]w[l]再减去更新的量,因此L2L2正则化又称为“权重衰减”。

1.5 为什么正则化可以减少过拟合

一种直观的理解如图7所示。



图7 正则化抑制过拟合的一种直观理解

加入正则化项以后,当λλ值较大时,权重w[l]w[l]将会趋近于0,这样原来复杂的神经网络中的很多节点的作用就会变得较小,而变为较简单的由一些关键的稀疏节点起主要作用的网络,类似于多层的logistic模型,这样就不会出现复杂的右图所示的过拟合现象,而是向左图变化。

下面以tanhtanh函数为例,继续深入理解。



图8 正则化对tanh函数输出的影响

当加入正则化项以后,w[l]w[l]的值显著减小,使得z[l]z[l]变为一个较小的值,tanhtanh函数在0值附近时接近线性的,当多层的神经网络的激活函数都处于线性阶段时,整体的神经网络模型就近似于线性模型,从而避免出现过拟合现象。

1.6 dropout正则化

随机失活(dropout)正则化是另一项非常有效的正则化方法。



图9 dropout正则化

以图9为例,对于一个训练样本,按照一定的概率随机删除一些节点,变为更小巧的网络结构,然后进行反向传播训练,如图10所示。



图10 dropout正则化

对于其他的训练样本,重复以上操作,随机删除节点,反向传播训练。

dropout的实现方法有很多,其中最常见的一种是反向随机失活(inverted dropout)。

以神经网络的第3层为例进行说明

'''用a3表示第三层激活值的输出,表示想要保留的节点的概率'''
keep-prob=0.8
np.random.rand(a[3].shape[0],a[3].shape[1])<keep-prob
a[3]=np.multiply(a[3],d[3])
a[3]/=keep-prob '''这就是反向随机失活,除以keep-prob是为了不影响a[4]的值'''
a[4]=w[4]*a[3]+b[4]


早期的dropout方法没有除以keep-prob,导致测试阶段的平均值很复杂。

1.7 理解dropout

上节中讲到dropout通过删除节点,将神经网络变为一个更小的模型,这和正则化的效果是一样的。



图11 正则化的直观理解

再以一个神经元为例进行说明,图11中这4个输入是随机删除的,这就使得权重在训练时不能过多的依赖于某个输入,而是将权重分摊开来,dropout将会达到收缩权重的平方范数的效果,和L2正则化的作用类似,dropout能够压缩权重。但是不同的是,L2正则化对不同权重的衰减是不同的,它取决于激活函数所乘的衰减项的大小。

一个dropout实施的例子如下所示。



图12 应用dropout正则化的神经网络例子

图12中的模型共有5层,每层的权重矩阵的维数分别为[7,3],[7,7],[3,7]

,[2,3],[1,2],由于第2层隐藏层的权重矩阵最大,为了防止矩阵的过拟合,可以设置keep-prob为一个较低的值(0.5),其它层过拟合概率较低,可以将keep-prob设置成一个较高的值(0.7)。也可以将输入层进行dropout操作,一般将keep-prob设置成一个较大的值,如0.9。总结起来,如果你担心某层会发生过拟合,你可以将每层的keep-prob设置成不同的值,缺点是在进行交叉验证时需要寻找更多的超参数,此外你也可以在某些层上应用dropout,而在其它层上不用dropout。

dropout在计算机视觉上很常见,这是因为输入图片的数据通常都很大,很难有足够大的数据集来防止过拟合。需要注意的是,dropout是一种正则化的方法,除非出现了过拟合,一般不会采用,因此,在其它领域,dropout较为少见。

dropout的一个缺点是代价函数不再被明确定义,因为每次迭代过程中,都会有些节点随机删除,使得代价函数并没有明确的意义,这样就失去了一个调试模型的工具。一种做法是,可以先关闭dropout,令keep-prob=1,调试模型使得代价函数单调下降,然后再打开dropout进行训练。

1.8其他正则化方法

除了dropout和L2正则化,还有一些其他的正则化方法。


图13 扩增数据的正则化方法

如图13所示,在检测猫的模型中,通过对猫的图片进行水平镜像、旋转、倾斜可以在无成本的前提下扩增数据。在数字识别的模型中,可以对数字进行扭曲等操作来扩充数据。扩增数据可以看作是一种正则化方法。

还有一种正则化方法叫做early stoopping,具体做法如下:


图14 early stopping

绘制训练集上代价函数随着迭代次数的变化曲线,同时验证集上的代价函数的变化曲线。一般情况下,验证集上的代价函数是先下降后上升的,这是因为在训练开始前权重ww一般是很小的,随着迭代和训练次数的增加,权重ww会逐渐增大,出现过拟合的现象。early stoopping的做法是在迭代过程的中间停止训练,从而得到大小适中的权重ww。

但是early stoopping也有缺点。机器学习的训练过程可以分为优化代价函数和防止正则化两个过程,这两个过程是正交的,也就是可以先重点考虑降低代价函数,而不考虑其他因素,再想办法来抑制过拟合。而early stopping则是同时完成这两个任务,在降低代价函数的同时又想不产生过拟合,这时需要考虑的东西就很多。使用L2L2正则化虽然会耗费更多的训练时间,并尝试很多的超参数λλ,但是在寻找超参数时更加容易。

1.9 归一化输入

在模型训练过程中,一个加速训练过程的方法是归一化输入。归一化输入分为两个步骤:

1.零均值化,将输入xx减去均值μμ

μ=1m∑mi=1x(i)μ=1m∑i=1mx(i)

x:=x−μ<
20000
/nobr>x:=x−μ

在完成第一步后,进行第二步

2.归一化方差

σ2=1m∑mi=1x(i)2σ2=1m∑i=1mx(i)2

x/=σ2x/=σ2

归一化输入的效果如图15所示。


图15 归一化输入

如果在训练集上进行了归一化输入,那么在验证和测试集上使用相同的μμ和σ2σ2。

那么为什么要进行归一化输入呢?

如果不同纬度的输入数据的值的范围差别很大的话,会导致训练出的权重和偏置取值范围差别很大,例如w1w1的取值为0~1000,w2w2的取值为0~1。以下图为例进行说明。


图16 归一化输入的原因

当不进行归一化输入时,输入空间范围狭长,当进行梯度下降时需要用很小的学习速率进行训练,计算成本巨大。而进行归一化输入以后,输入空间更加对称,无论从哪里开始训练,模型都能快速的达到代价函数的最小值。

1.10 梯度消失与梯度爆炸

在训练神经网络特别是深层神经网络时,一个可能面临的问题是梯度消失或梯度爆炸,也就是说在训练时导数或者叫梯度会很大或者很小,这会增加训练的难度。



图17 一个简化的深层神经网络

图17是一个L层的深层神经网络模型,假设激活函数为线性函数g(z)=zg(z)=z,b=0b=0,那么:

y^=w[L]w[L−1]⋅⋅⋅w[3]w[2]w[1]y^=w[L]w[L−1]⋅⋅⋅w[3]w[2]w[1]

如果忽略最后一层,剩余层的权重都为大于1的值:

wl=[1.5001.5]wl=[1.5001.5]

则有

y^=w[L][1.5001.5]L−1xy^=w[L][1.5001.5]L−1x

对于一个很深的神经网络,激活函数的值将会呈指数级的增长,变为一个很大的值。

如果忽略最后一层,剩余层的权重都为小于1的值:

wl=[0.5000.5]wl=[0.5000.5]

则有

y^=w[L][0.5000.5]L−1xy^=w[L][0.5000.5]L−1x

对于一个很深的神经网络,激活函数的值将会呈指数级的减小,变为一个很小的值。

虽然上面讲的是激活函数的值,但是实际上梯度也有类似的规律,特别是梯度按照指数倍的减小时,模型会变得越来越难以训练。

1.11 神经网络的权重初始化

上节讲到了梯度消失与梯度爆炸,这节将介绍一个可能有效的办法。以图18为例,



图18 一个神经元示例

对于ll层有nl−1nl−1个输入,

z=w1x1+x2x2+w3x3...+wnl−1xnl−1z=w1x1+x2x2+w3x3...+wnl−1xnl−1

设置wiwi的方差为1nl1nl,权重的初始化代码如下:

w[l]=np.random.randn(w[l].shape)*np.sqrt(1/n[l-1])


对于ReLU函数,方差取2n[l−1]2n[l−1]效果更好,此外还有Bengio提出的方差为2n[l−1]+n[l]2n[l−1]+n[l]的方法。

1.12 梯度的数值逼近

本节讲叙了求解一阶导数时向前差分、向后差分和中心差分的区别,向前差分和向后差分的误差量级为O(h)O(h),而中心差分的误差量级为O(h2)O(h2),其中hh为步长,所以中心差分法更为精确。

1.13 梯度检验

梯度检验(gradient checking)可以帮助你发现backprop过程中的bug,可以节省大量的时间。具体操作如下:

将所有的参数W[1],b[1],W[2],b[2]...W[L],b[L]W[1],b[1],W[2],b[2]...W[L],b[L]放入一个向量θθ中;

将所有的参数dW[1],db[1],dW[2],db[2]...dW[L],db[L]dW[1],db[1],dW[2],db[2]...dW[L],db[L]放入一个向量dθdθ中。

这时,代价函数JJ就变为θθ的函数,J(θ1,θ2,θ3,...,θn)J(θ1,θ2,θ3,...,θn)

首先如下循环:

for i in n:for i in n:

dθ[i]appro=J(θ1,θ2,...,θi+ϵ,...,θn)−J(θ1,θ2,...,θi−ϵ,...,θn)2ϵdθappro[i]=J(θ1,θ2,...,θi+ϵ,...,θn)−J(θ1,θ2,...,θi−ϵ,...,θn)2ϵ

得到的dθ[i]approdθappro[i]就是∂J∂θ[i]∂J∂θ[i]的估计值,dθapprodθappro向量就是按照中心差分法得到的梯度近似值。

然后,看dθapprodθappro和dθdθ是否近似相等来判断梯度下降法得到的dθdθ是否正确。

具体实现方法是计算两个向量的欧几里德范数,并用向量长度做归一化。

var=||dθappro−dθ||2||dθappro||2+||dθ||2var=||dθappro−dθ||2||dθappro||2+||dθ||2这个表达式中只有下标2,没有上标,代表了对平方和进行开方。

在分析结果时,如果ϵϵ的取值为10−710−7,如果计算得到的varvar为10−710−7,则认为模型训练良好,如果varvar为10−510−5,则要小心是否某一项误差较大,如果varvar为10−310−3,则要重点检查下模型中的bug了。

1.14 关于梯度检验实现的注记

1.不要在训练中使用梯度检验,它只用于debug。

2.如果梯度检验失败了,仔细检查组件,确定在哪些地方出现了bug。

3.使用正则化。

4.不要同时使用梯度检验和dropout。由于dropout随机删除节点,每次梯度检验的向量输入都不同,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐