吴恩达【优化深度神经网络】笔记01——深度学习的实用层面

引言

在接下来的几次笔记中,我们将对第二门课《Improving Deep Neural Networks: Hyperparameter tuning, Regularization and Optimization》进行笔记总结和整理。我们在第一门课中已经学习了如何建立一个神经网络,或者浅层的,或者深度的。而这第二门课,我们将着重讨论和研究如何优化神经网络模型,例如调整超参数,提高算法运行速度等等

一、训练集/验证集/测试集(Train/Dev/Test sets)

选择最佳的训练集(Training sets)、验证集(Development sets)、测试集(Test sets) 对神经网络的性能影响非常重要。

除此之外,在构建一个神经网络的时候,我们需要设置许多参数,例如神经网络的层数、每个隐藏层包含的神经元个数、学习因子(学习速率)、激活函数的选择等等。实际上很难在第一次设置的时候就选择到这些最佳的参数,而是需要通过不断地迭代更新来获得

这个循环迭代的过程是这样的:我们先有个想法Idea,先选择初始的参数值,构建神经网络模型结构。然后通过代码Code的形式,实现这个神经网络。最后,通过实验Experiment验证这些参数对应的神经网络的表现性能。根据验证结果,我们对参数进行适当的调整优化,再进行下一次的Idea->Code->Experiment循环。通过很多次的循环,不断调整参数,选定最佳的参数值,从而让神经网络性能最优化
在这里插入图片描述
深度学习已经应用于许多领域中,比如NLP,CV,Speech Recognition等等。通常来说,最适合某个领域的深度学习网络往往不能直接应用在其它问题上。解决不同问题的最佳选择是根据样本数量、输入特征数量和电脑配置信息(GPU或者CPU)等,来选择最合适的模型。即使是最有经验的深度学习专家也很难第一次就找到最合适的参数。因此,应用深度学习是一个反复迭代的过程,需要通过反复多次的循环训练得到最优化参数。 决定整个训练过程快慢的关键在于单次循环所花费的时间,单次循环越快,训练过程越快。而设置合适的Train/Dev/Test sets数量,能有效提高训练效率。

一般地,我们将所有的样本数据分成三个部分:Train/Dev/Test sets。

  • Train sets:用训练集对算法或模型进行训练过程;
  • Dev sets:利用验证集(又称为简单交叉验证集,hold-out cross validation set)进行交叉验证,选择出最好的模型;
  • Test sets:利用测试集对模型进行测试,获取模型运行的无偏估计(对学习方法进行评估),用来测试最好算法的实际表现。
1. 数据集选择

小数据量时代,如100、1000、10000的数据量大小,可以将数据集按照以下比例进行划分:

  • 无验证集的情况:70% / 30%
  • 有验证集的情况:60% / 20% / 20%

而在如今的大数据时代,对于一个问题,我们拥有的数据集的规模可能是百万级别的,所以验证集和测试集所占的比重会趋向于变得更小。
验证集的目的是为了验证不同的算法哪种更加有效,所以验证集只要足够大到能够验证大约 2-10 种算法哪种更好,而不需要使用 20% 的数据作为验证集。如百万数据中抽取 1 万的数据作为验证集就可以了。
测试集的主要目的是评估模型的效果,如在单个分类器中,往往在百万级别的数据中,我们选择其中 1000 条数据足以评估单个模型的效果。

  • 100万数据量:98% / 1% / 1%
  • 超百万数据量:99.5% / 0.25% / 0.25%(或者99.5% / 0.4% / 0.1%)

现代深度学习还有个重要的问题就是训练样本和测试样本分布上不匹配,意思是训练样本和测试样本来自于不同的分布。举个例子,假设你开发一个手机app,可以让用户上传图片,然后app识别出猫的图片。在app识别算法中,你的训练样本可能来自网络下载,而你的验证和测试样本可能来自不同用户的上传。从网络下载的图片一般像素较高而且比较正规,而用户上传的图片往往像素不稳定,且图片质量不一。因此,训练样本和验证/测试样本可能来自不同的分布。解决这一问题的比较科学的办法是尽量保证Dev sets和Test sets来自于同一分布。值得一提的是,训练样本非常重要,通常我们可以将现有的训练样本做一些处理,例如图片的翻转、假如随机噪声等,来扩大训练样本的数量,从而让该模型更加强大。即使Train sets和Dev/Test sets不来自同一分布,使用这些技巧也能提高模型性能。

如果没有Test sets也是没有问题的Test sets的目标主要是进行无偏估计。 我们可以通过Train sets训练不同的算法模型,然后分别在Dev sets上进行验证,根据结果选择最好的算法模型。这样也是可以的,不需要再进行无偏估计了。如果只有Train sets和Dev sets,通常也有人把这里的Dev sets称为Test sets,我们要注意加以区别。

2. 补充:交叉验证(cross validation)

交叉验证的基本思想是重复地使用数据;把给定的数据进行切分,将切分的数据集组合为训练集与测试集,在此基础上反复地进行训练、测试以及模型选择。

二、偏差和方差(Bias/Variance)

偏差(Bias)和方差(Variance)是机器学习领域非常重要的两个概念和需要解决的问题。在传统的机器学习算法中,Bias和Variance是对立的,分别对应着欠拟合和过拟合,我们常常需要在Bias和Variance之间进行权衡。而在深度学习中,我们可以同时减小Bias和Variance,构建最佳神经网络模型

如下图所示,显示了二维平面上,high bias,just right,high variance的例子。可见,high bias对应着欠拟合,而high variance对应着过拟合。
在这里插入图片描述
上图这个例子中输入特征是二维的,high bias和high variance可以直接从图中分类线看出来。而对于输入特征是高维的情况,如何来判断是否出现了high bias或者high variance呢?

1. “偏差-方差分解”(bias-variance decomposition)

“偏差-方差分解”(bias-variance decomposition)是解释学习算法泛化性能的一种重要工具。

泛化误差可分解为偏差、方差与噪声之和:

  • 偏差:度量了学习算法的期望预测与真实结果的偏离程度,即刻画了学习算法本身的拟合能力;
  • 方差:度量了同样大小的训练集的变动所导致的学习性能的变化,即刻画了数据扰动所造成的影响;
  • 噪声:表达了在当前任务上任何学习算法所能够达到的期望泛化误差的下界,即刻画了学习问题本身的难度。

偏差-方差分解说明,泛化性能是由学习算法的能力、数据的充分性以及学习任务本身的难度所共同决定的。 给定学习任务,为了取得好的泛化性能,则需要使偏差较小,即能够充分拟合数据,并且使方差较小,即使得数据扰动产生的影响小。

在**欠拟合(underfitting)的情况下,出现高偏差(high bias)**的情况,即不能很好地对数据进行分类。

当模型设置的太复杂时,训练集中的一些噪声没有被排除,使得模型出现过拟合(overfitting) 的情况,在验证集上出现高方差(high variance) 的现象。

2. 输入特征是高维的情况

继续回答 “对于输入特征是高维的情况,如何来判断是否出现了high bias或者high variance” 这个问题。

例如猫识别问题,输入是一幅图像,其特征维度很大。这种情况下,我们可以通过两个数值Train set error和Dev set error来理解bias和variance。假设Train set error为1%,而Dev set error为11%,即该算法模型对训练样本的识别很好,但是对验证集的识别却不太好。这说明了该模型对训练样本可能存在过拟合,模型泛化能力不强,导致验证集识别率低。这恰恰是high variance的表现。假设Train set error为15%,而Dev set error为16%,虽然二者error接近,即该算法模型对训练样本和验证集的识别都不是太好。这说明了该模型对训练样本存在欠拟合。这恰恰是high bias的表现。假设Train set error为15%,而Dev set error为30%,说明了该模型既存在high bias也存在high variance(深度学习中最坏的情况)。再假设Train set error为0.5%,而Dev set error为1%,即low bias和low variance,是最好的情况。值得一提的是,以上的这些假设都是建立在base error是0的基础上,即人类都能正确识别所有猫类图片。base error不同,相应的Train set error和Dev set error会有所变化,但没有相对变化。

简单总结一下,当训练出一个模型以后,如果:

  • 训练集的错误率较小,而验证集的错误率却较大,说明模型存在较大方差,可能出现了过拟合;
  • 训练集和开发集的错误率都较大,且两者相当,说明模型存在较大偏差,可能出现了欠拟合;
  • 训练集错误率较大,且开发集的错误率远较训练集大,说明方差和偏差都较大,模型很差;
  • 训练集和开发集的错误率都较小,且两者的相差也较小,说明方差和偏差都较小,这个模型效果比较好。

一般来说,Train set error体现了是否出现bias,Dev set error体现了是否出现variance(正确地说,应该是Dev set error与Train set error的相对差值)。

偏差和方差的权衡问题对于模型来说十分重要。最优误差通常也称为“贝叶斯误差”。

我们已经通过二维平面展示了high bias或者high variance的模型,下图展示了high bias and high variance的模型:
在这里插入图片描述
模型既存在high bias也存在high variance,可以理解成某段区域是欠拟合的,某段区域是过拟合的。

3. 应对方法

存在高偏差:

  • 扩大网络规模,如添加隐藏层或隐藏单元数目;
  • 寻找合适的网络架构,使用更复杂的 NN 结构;
  • 花费更长时间训练。

存在高方差:

  • 获取更多的数据;
  • 正则化(regularization);
  • 寻找更合适的网络结构。

不断尝试,直到找到低偏差、低方差的框架。 在深度学习的早期阶段,没有太多方法能做到只减少偏差或方差而不影响到另外一方。而在大数据时代,深度学习对监督式学习大有裨益,使得我们不用像以前一样太过关注如何平衡偏差和方差的权衡问题,通过以上方法可以在不增加某一方的前提下减少另一方的值。

三、正则化(regularization)

如果出现了过拟合,即high variance,则需要采用正则化regularization来解决。虽然扩大训练样本数量也是减小high variance的一种方法,但是通常获得更多训练样本的成本太高,比较困难。所以,更可行有效的办法就是使用regularization。正则化是在成本函数中加入一个正则化项,惩罚模型的复杂度。正则化可以用于解决高方差的问题

1. L2 regularization

首先,我们先来回顾一下之前学过的Logistic regression,若采用L2 regularization,其表达式为:
在这里插入图片描述
其中,
在这里插入图片描述
这里有个问题:为什么只对w进行正则化而不对b进行正则化呢?其实也可以对b进行正则化。但是一般w的维度很大,而b只是一个常数。相比较来说,参数很大程度上由w决定,改变b值对整体模型影响较小。 所以,一般为了简便,就忽略对b的正则化了。

2. L1 regularization

除了L2 regularization之外,还有另外一只正则化方法:L1 regularization。其表达式为:
在这里插入图片描述
其中,
在这里插入图片描述
其中,λ 为正则化因子,是超参数。

与L2 regularization相比,L1 regularization得到的w更加稀疏,即很多w为零值。其优点是节约存储空间,因为大部分w为0。然而,实际上L1 regularization在解决high variance方面比L2 regularization并不更具优势。而且,L1的在微分求导方面比较复杂。所以,一般L2 regularization更加常用。

L1、L2 regularization中的 λ λ λ 就是正则化参数(超参数的一种)。可以设置 λ λ λ 为不同的值,在Dev set中进行验证,选择最佳的 λ λ λ 。顺便提一下,在python中,由于lambda是保留字,所以为了避免冲突,我们使用lambd来表示 λ λ λ

3. 神经网络中的正则化

对于神经网络,加入正则化的成本函数:
在这里插入图片描述
其中,|| w w w [ l ] [l] [l]|| 2 2 2称为Frobenius范数,记为|| w w w [ l ] [l] [l]|| 2 2 2 F F F.
在这里插入图片描述
一个矩阵的Frobenius范数就是计算所有元素平方和再开方,如下所示:
在这里插入图片描述
所以神经网络中的正则化项被称为弗罗贝尼乌斯范数矩阵。

4. 权重衰减(weight decay)

值得注意的是,由于加入了正则化项,梯度下降算法中的 d w dw dw [ l ] [l] [l] 计算表达式需要做如下修改:
在这里插入图片描述
代入梯度更新公式:
在这里插入图片描述
L2 regularization也被称做weight decay。这是因为,由于加上了正则项, d w dw dw [ l ] [l] [l] 有个增量,在更新 w w w [ l ] [l] [l] 的时候,会多减去这个增量,使得 w w w [ l ] [l] [l] 比没有正则项的值要小一些。不断迭代更新,不断地减小。
在这里插入图片描述
简单来说,因为红色框子中的那一项小于1,也就是说更新后会给原来的 w w w [ l ] [l] [l] 一个衰减的参数。因此,L2 正则化项也被称为权重衰减(Weight Decay)。

四、正则化可以减小过拟合的原因(Why regularization reduces overfitting)

1. 直观解释

正则化因子设置的足够大的情况下,为了使成本函数最小化,权重矩阵 W 就会被设置为接近于 0 的值,直观上相当于消除了很多神经元的影响,那么大的神经网络就会变成一个较小的网络。当然,实际上隐藏层的神经元依然存在,但是其影响减弱了,便不会导致过拟合。

2. 数学解释

假设神经元中使用的激活函数为 g ( z ) = t a n h ( z ) g(z) = tanh(z) g(z)=tanh(z)(sigmoid 同理)。tanh函数的特点是在 z z z 接近零的区域,函数近似是线性的,而当 ∣ z ∣ |z| z 很大的时候,函数非线性且变化缓慢。
在这里插入图片描述
当使用正则化, λ λ λ 较大,即对权重 w w w [ l ] [l] [l] 的惩罚较大, w w w [ l ] [l] [l] 减小。 z z z [ l ] [l] [l] = w w w [ l ] [l] [l] a a a [ l − 1 ] [l-1] [l1] + b b b [ l ] [l] [l] 便会减小。在 z 较小(接近于 0)的区域里,tanh(z)函数近似线性,所以每层的函数就近似线性函数整个网络就成为一个简单的近似线性的网络,因此不会发生过拟合。此时的 z z z [ l ] [l] [l] 分布在tanh函数的近似线性区域。那么这个神经元起的作用就相当于是linear regression。如果每个神经元对应的权重 w w w [ l ] [l] [l] 都比较小,那么整个神经网络模型相当于是多个linear regression的组合,即可看成一个linear network。得到的分类超平面就会比较简单,不会出现过拟合现象。

3. 其他解释

在权值 w w w [ l ] [l] [l] 变小之下,输入样本 X X X 随机的变化不会对神经网络模造成过大的影响,神经网络受局部噪音的影响的可能性变小。这就是正则化能够降低模型方差的原因。

五、Dropout正则化(Dropout Regularization)

除了L2 regularization之外,还有另外一种防止过拟合的有效方法:Dropout。

Dropout是指在深度学习网络的训练过程中,对于每层的神经元,按照一定的概率将其暂时从网络中丢弃。也就是说,每次训练时,每一层都有部分神经元不工作,起到简化复杂网络模型的效果,从而避免发生过拟合。
在这里插入图片描述
简而言之,dropout(随机失活)是在神经网络的隐藏层为每个神经元结点设置一个随机消除的概率,保留下来的神经元形成一个结点较少、规模较小的网络用于训练。dropout 正则化较多地被使用在计算机视觉(Computer Vision)领域

知乎上一个答主讲解的很好,在这里放上链接:CNN 入门讲解:什么是dropout?
在这里插入图片描述
该例中,一个模型的作用效果,也转变成4个模型的效果和,更像一个多模型投票。

1. 反向失活(Inverted dropout)

Dropout有不同的实现方法,接下来介绍一种常用的方法:Inverted dropout。

假设对于第 l l l 层神经元,设定保留神经元比例概率keep_prob=0.8,即该层有20%的神经元停止工作。 d l dl dl 为dropout向量,设置 d l dl dl 为随机vector,其中80%的元素为1,20%的元素为0。在python中可以使用如下语句生成dropout vector:

dl = np.random.rand(al.shape[0],al.shape[1])<keep_prob

然后,第 l l l 层经过dropout,随机删减20%的神经元,只保留80%的神经元,其输出为:

al = np.multiply(al,dl)

最后,还要对 a l al al 进行scale up处理,即:

al /= keep_prob

最后一步al /= keep_prob是因为 a a a [ l ] [l] [l] 中的一部分元素失活(相当于被归零)。为了在下一层计算时不影响 z z z [ l + 1 ] [l+1] [l+1] = w w w [ l + 1 ] [l+1] [l+1] a a a [ l ] [l] [l] + b b b [ l + 1 ] [l+1] [l+1] 的期望值,即 a l al al 作为下一层神经元的输入值尽量保持不变。因此除以一个keep_prob。

举一个简单的例子,假设第 l l l 层有50个神经元,经过dropout后,有10个神经元停止工作,这样只有40神经元有作用。那么得到的 a l al al 只相当于原来的80%。scale up后,能够尽可能保持 a l al al 的期望值相比之前没有大的变化。

Inverted dropout的另外一个好处就是在对该dropout后的神经网络进行测试时能够减少scaling问题。因为在训练时,使用scale up保证 a l al al 的期望值没有大的变化,测试时就不需要再对样本数据进行类似的尺度伸缩操作了。

2. 理解 dropout(Understanding Dropout)

Dropout通过每次迭代训练时,随机选择不同的神经元,相当于每次都在不同的神经网络上进行训练,类似机器学习中Bagging的方法(三个臭皮匠,赛过诸葛亮),能够防止过拟合。

除此之外,还可以从权重w的角度来解释为什么dropout能够有效防止过拟合。对于某个神经元来说,某次训练时,它的某些输入在dropout的作用被过滤了。而在下一次训练时,又有不同的某些输入被过滤。经过多次训练后,某些输入被过滤,某些输入被保留。**这样,该神经元就不会受某个输入非常大的影响,影响被均匀化了。**也就是说,对应的权重w不会很大。这从从效果上来说,与L2 regularization是类似的,都是对权重w进行“惩罚”,减小了w的值。
在这里插入图片描述
总结一下,对于同一组训练数据,利用不同的神经网络训练之后,求其输出的平均值可以减少overfitting。 Dropout就是利用这个原理,每次丢掉一定数量的隐藏层神经元,相当于在不同的神经网络上进行训练,这样就减少了神经元之间的依赖性,即每个神经元不能依赖于某几个其他的神经元(指层与层之间相连接的神经元),使神经网络更加能学习到与其他神经元之间的更加健壮robust的特征。

对于不同的层,设置的keep_prob也不同。一般来说,神经元较少的层,会设keep_prob为 1.0,而神经元多的层则会设置比较小的keep_prob

dropout 的一大缺点是成本函数无法被明确定义。因为每次迭代都会随机消除一些神经元结点的影响,因此无法确保成本函数单调递减。因此,使用 dropout 时,先将keep_prob全部设置为 1.0 后运行代码,确保 J ( w , b ) J(w,b) J(w,b) 函数单调递减,再打开 dropout。

3. 为什么说Dropout可以解决过拟合?
  • 取平均的作用: 整个dropout过程就相当于对很多个不同的神经网络取平均。而不同的网络产生不同的过拟合,一些互为“反向”的拟合相互抵消就可以达到整体上减少过拟合。
  • 减少神经元中之间复杂的共适应关系: 因为dropout程序导致两个神经元不一定每次都在一个dropout网络中出现。这样权值的更新不再依赖于有固定关系的隐含节点的共同作用,阻止了某些特征仅仅在其它特定特征下才有效果的情况 。迫使网络去学习更加鲁棒的特征 ,这些特征在其它的神经元的随机子集中也存在。换句话说假如我们的神经网络是在做出某种预测,它不应该对一些特定的线索片段太过敏感,即使丢失特定的线索,它也应该可以从众多其它线索中学习一些共同的特征。
  • Dropout类似于性别在生物进化中的角色: 物种为了生存往往会倾向于适应这种环境,环境突变则会导致物种难以做出及时反应,性别的出现可以繁衍出适应新环境的变种,有效的阻止过拟合,即避免环境改变时物种可能面临的灭绝。

这里参考了文章:Dropout(正则化)

六、其他正则化方法(Other regularization methods)

除了L2 regularization和dropout regularization之外,还有其它减少过拟合的方法。一种方法是增加训练样本数量。但是通常成本较高,难以获得额外的训练样本。但是,我们可以对已有的训练样本进行一些处理来“制造”出更多的样本,称为data augmentation。

1. 数据扩增(Data Augmentation)

通过图片的一些变换(翻转,局部放大后切割等),得到更多的训练集和验证集。
例如图片识别问题中,可以对已有的图片进行水平翻转、垂直翻转、任意角度旋转、缩放或扩大等等。如下图所示,这些处理都能“制造”出新的训练样本。虽然这些是基于原有样本的,但是对增大训练样本数量还是有很有帮助的,不需要增加额外成本,却能起到防止过拟合的效果。
在这里插入图片描述
在数字识别中,也可以将原有的数字图片进行任意旋转或者扭曲,或者增加一些noise,如下图所示:
在这里插入图片描述

2. 早停止法(Early Stopping)

一个神经网络模型随着迭代训练次数增加,train set error一般是单调减小的,而dev set error 先减小,之后又增大。也就是说训练次数过多时,模型会对训练样本拟合的越来越好,但是对验证集拟合效果逐渐变差,即发生了过拟合。因此,迭代训练次数不是越多越好,可以通过train set error和dev set error随着迭代次数的变化趋势,选择合适的迭代次数,即early stopping。
在这里插入图片描述
然而,Early stopping有其自身缺点。通常来说,机器学习训练模型有两个目标:一是优化cost function,尽量减小J;二是防止过拟合。 这两个目标彼此对立的,即减小J的同时可能会造成过拟合,反之亦然。我们把这二者之间的关系称为正交化orthogonalization。该节课开始部分就讲过,在深度学习中,我们可以同时减小Bias和Variance,构建最佳神经网络模型。但是,Early stopping的做法通过减少迭代训练次数来防止过拟合,这样J就不会足够小。也就是说,early stopping将上述两个目标融合在一起,同时优化,但可能没有“分而治之”的效果好。
在这里插入图片描述

与early stopping相比,L2 regularization可以实现“分而治之”的效果:迭代训练足够多,减小J,而且也能有效防止过拟合。而L2 regularization的缺点之一是最优的正则化参数 λ λ λ 的选择比较复杂。对这一点来说,early stopping比较简单。总的来说,L2 regularization更加常用一些。

更详细的介绍请看:深度学习技巧之Early Stopping(早停法)

七、标准化输入(Normalizing inputs)

在训练神经网络时,标准化输入可以提高训练的速度。标准化输入就是对训练数据集进行归一化的操作,即将原始数据减去其均值 μ μ μ 后,再除以其方差 σ σ σ2

均值 μ μ μ
在这里插入图片描述
方差 σ σ σ2
在这里插入图片描述
归一化:
在这里插入图片描述
以二维平面为例,下图展示了其归一化过程:
在这里插入图片描述
值得注意的是,由于训练集进行了标准化处理,那么对于测试集或在实际应用时,应该使用同样的 μ μ μ σ σ σ2 对其进行标准化处理。这样保证了训练集合测试集的标准化操作一致。

之所以要对输入进行标准化操作,主要是为了让所有输入归一化同样的尺度上,方便进行梯度下降算法时能够更快更准确地找到全局最优解。 假如输入特征是二维的,且 x 1 x1 x1的范围是[1,1000], x 2 x2 x2的范围是[0,1]。如果不进行标准化处理, x 1 x1 x1 x 2 x2 x2之间分布极不平衡,训练得到的 w 1 w1 w1 w 2 w2 w2也会在数量级上差别很大。这样导致的结果是cost function与 w w w b b b 的关系可能是一个非常细长的椭圆形碗 。对其进行梯度下降算法时,由于 w 1 w1 w1 w 2 w2 w2数值差异很大,只能选择很小的学习因子 α α α,来避免 J J J 发生振荡。一旦 α α α 较大,必然发生振荡, J J J 不再单调下降。如下图所示。
在这里插入图片描述

然而,如果进行了标准化操作 x 1 x1 x1 x 2 x2 x2分布均匀, w 1 w1 w1 w 2 w2 w2数值差别不大,得到的cost function与 w w w b b b 的关系是类似圆形碗 。对其进行梯度下降算法时, α α α 可以选择相对大一些,且 J J J一般不会发生振荡,保证了 J J J 是单调下降的。如下图所示。
在这里插入图片描述
另外一种情况,如果输入特征之间的范围本来就比较接近,那么不进行标准化操作也是没有太大影响的。但是,标准化处理在大多数场合下还是值得推荐的。

简而言之,在不使用标准化 的成本函数中,如果设置一个较小的学习率,可能需要很多次迭代才能到达全局最优解;而如果使用了标准化 ,那么无论从哪个位置开始迭代,都能以相对较少的迭代次数找到全局最优解

八、梯度消失和梯度爆炸(Vanishing and Exploding gradients)

在梯度函数上出现的以指数级递增或者递减的情况分别称为梯度爆炸或者梯度消失。
举个例子来说明,假设一个多层的每层只包含两个神经元的深度神经网络模型,如下图所示:
在这里插入图片描述
为了简化复杂度,便于分析,我们令各层的激活函数为线性函数,即 g ( Z ) = Z g(Z)=Z g(Z)=Z。且忽略各层常数项 b b b 的影响,令 b b b 全部为零。那么,该网络的预测输出为:
在这里插入图片描述

  • 对于 w w w [ l ] [l] [l] 的值大于 1 的情况,激活函数的值将以指数级递增;
  • 对于 w w w [ l ] [l] [l] 的值小于 1 的情况,激活函数的值将以指数级递减。

对于导数同理。因此,在计算梯度时,根据不同情况梯度函数会以指数级递增或递减,导致训练导数难度上升,梯度下降算法的步长会变得非常小,需要训练的时间将会非常长。

1. 利用初始化缓解梯度消失和爆炸(Weight Initialization for Deep Networks)

根据 z z z = = = w w w 1 1 1 x x x 1 1 1 + + + w w w 2 2 2 x x x 2 2 2 + . . . . + + .... + +....+ w w w n n n x x x n n n + + + b b b 可知,当输入的数量 n 较大时,我们希望每个 w w w i i i 的值都小一些,这样它们的和得到的 z z z 也较小。

为了得到较小的 w w w i i i ,设置Var(wi)=1/n,这里称为Xavier initialization。相应的python伪代码为:

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

这样,激活函数的输入 x 近似设置成均值为 0,标准方差为 1,神经元输出 z 的方差就正则化到 1 了。虽然没有解决梯度消失和爆炸的问题,但其在一定程度上确实减缓了梯度消失和爆炸的速度。

同理,也有 He Initialization。它和 Xavier initialization 唯一的区别是Var(wi)=2/n,适用于 ReLU 作为激活函数时。

总结:当激活函数使用 ReLU 时,Var(wi)=2/n;当激活函数使用 tanh 时,Var(wi)=1/n

至于选择哪种初始化方法因人而异,可以根据不同的激活函数选择不同方法。另外,我们可以对这些初始化方法中设置某些参数,作为超参数,通过验证集进行验证,得到最优参数,来优化神经网络。

九、梯度检验(Gradient checking)

Back Propagation神经网络有一项重要的测试是梯度检查(gradient checking)。其目的是检查验证反向传播过程中梯度下降算法是否正确。

1. 梯度的数值逼近(Numerical approximation of gradients)

该小节将先介绍如何近似求出梯度值。

  • 单边误差(one-sided-difference)
    在这里插入图片描述
    误差: O ( ε ) O(ε) O(ε)

  • 双边误差(two-sided-difference)
    在这里插入图片描述
    误差: O O O2)

ε ε ε 越小时,结果越接近真实的导数,也就是梯度值。可以使用这种方法来判断反向传播进行梯度下降时,是否出现了错误。
在这里插入图片描述
利用微分思想,函数 f f f θ θ θ 处的梯度可以表示成:
在这里插入图片描述
其中, ε > 0 ε>0 ε>0,且足够小。

使用双边误差的方法去逼近导数,精度要高于单边误差。

2. 梯度检验的实施(Gradient checking)

介绍完如何近似求出梯度值后,我们将介绍如何进行梯度检查,来验证训练过程中是否出现bugs。

梯度检查首先要做的是分别将 W W W [ 1 ] [1] [1] b b b [ 1 ] [1] [1],…, W W W [ L ] [L] [L] b b b [ L ] [L] [L]这些矩阵构造成一维向量,然后将这些一维向量组合起来构成一个更大的一维向量 θ θ θ。这样cost function J J J( W W W [ 1 ] [1] [1] b b b [ 1 ] [1] [1],…, W W W [ L ] [L] [L] b b b [ L ] [L] [L])就可以表示成 J ( θ ) J(θ) J(θ)

然后将反向传播过程通过梯度下降算法得到的 d W dW dW [ 1 ] [1] [1] d b db db [ 1 ] [1] [1],…, d W dW dW [ L ] [L] [L] d b db db [ L ] [L] [L]按照一样的顺序构造成一个一维向量 d θ dθ dθ d θ dθ dθ的维度与 θ θ θ一致。

接着利用 J ( θ ) J(θ) J(θ) 对每个 θ θ θ i i i 计算近似梯度,其值与反向传播算法得到的 d θ dθ dθ i i i 相比较,检查是否一致。例如,对于第 i i i 个元素,近似梯度为:
在这里插入图片描述
计算完所有 θ θ θ i i i 的近似梯度后,可以计算 d θ dθ dθ a p p r o x approx approx d θ dθ dθ 的欧氏(Euclidean)距离来比较二者的相似度。公式如下:
在这里插入图片描述
一般来说,如果欧式距离越小,例如 10 10 10 − 7 -7 7 甚至更小,则表明 d θ dθ dθ a p p r o x approx approx d θ dθ dθ 越接近,即反向梯度计算是正确的,没有bugs。如果欧式距离较大,例如 10 10 10 − 5 -5 5 ,则表明梯度计算可能出现问题,需要再次检查是都有bugs存在。如果欧氏距离很大,例如 10 10 10 − 3 -3 3 甚至更大,则表明 d θ dθ dθ a p p r o x approx approx d θ dθ dθ 差别很大,则说明梯度下降计算过程有bugs,需要仔细检查。

3. 在神经网络实施梯度检验的实用技巧和注意事项(Gradient Checking Implementation Notes)
  1. 不要在整个训练过程中都进行梯度检查,仅仅作为debug使用。
  2. 如果梯度检查出现错误,找到对应出错的梯度,检查其推导是否出现错误。
  3. 注意不要忽略正则化项,计算近似梯度的时候要包括进去。
  4. 梯度检验不能与 dropout 同时使用。梯度检查时关闭dropout,检查完毕后再打开dropout。

参考文章:Coursera吴恩达《优化深度神经网络》课程笔记(1)-- 深度学习的实用层面

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值