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

红色石头的我的网站:redstonewill.compython

Andrew Ng的深度学习专项课程的第一门课《Neural Networks and Deep Learning》的5份笔记我已经整理完毕。迷路的小伙伴请见以下连接:web

Coursera吴恩达《神经网络与深度学习》课程笔记(1)– 深度学习概述算法

Coursera吴恩达《神经网络与深度学习》课程笔记(2)– 神经网络基础之逻辑回归网络

Coursera吴恩达《神经网络与深度学习》课程笔记(3)– 神经网络基础之Python与向量化app

Coursera吴恩达《神经网络与深度学习》课程笔记(4)– 浅层神经网络dom

Coursera吴恩达《神经网络与深度学习》课程笔记(5)– 深层神经网络机器学习

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

1. Train/Dev/Test sets

选择最佳的训练集(Training sets)、验证集(Development sets)、测试集(Test sets)对神经网络的性能影响很是重要。除此以外,在构建一个神经网络的时候,咱们须要设置许多参数,例如神经网络的层数、每一个隐藏层包含的神经元个数、学习因子(学习速率)、激活函数的选择等等。实际上很难在第一次设置的时候就选择到这些最佳的参数,而是须要经过不断地迭代更新来得到。这个循环迭代的过程是这样的:咱们先有个想法Idea,先选择初始的参数值,构建神经网络模型结构;而后经过代码Code的形式,实现这个神经网络;最后,经过实验Experiment验证这些参数对应的神经网络的表现性能。根据验证结果,咱们对参数进行适当的调整优化,再进行下一次的Idea->Code->Experiment循环。经过不少次的循环,不断调整参数,选定最佳的参数值,从而让神经网络性能最优化。svg

这里写图片描述

深度学习已经应用于许多领域中,好比NLP,CV,Speech Recognition等等。一般来讲,最适合某个领域的深度学习网络每每不能直接应用在其它问题上。解决不一样问题的最佳选择是根据样本数量、输入特征数量和电脑配置信息(GPU或者CPU)等,来选择最合适的模型。即便是最有经验的深度学习专家也很难第一次就找到最合适的参数。所以,应用深度学习是一个反复迭代的过程,须要经过反复屡次的循环训练获得最优化参数。决定整个训练过程快慢的关键在于单次循环所花费的时间,单次循环越快,训练过程越快。而设置合适的Train/Dev/Test sets数量,能有效提升训练效率。函数

通常地,咱们将全部的样本数据分红三个部分:Train/Dev/Test sets。Train sets用来训练你的算法模型;Dev sets用来验证不一样算法的表现状况,从中选择最好的算法模型;Test sets用来测试最好算法的实际表现,做为该算法的无偏估计。

以前人们一般设置Train sets和Test sets的数量比例为70%和30%。若是有Dev sets,则设置比例为60%、20%、20%,分别对应Train/Dev/Test sets。这种比例分配在样本数量不是很大的状况下,例如100,1000,10000,是比较科学的。可是若是数据量很大的时候,例如100万,这种比例分配就不太合适了。科学的作法是要将Dev sets和Test sets的比例设置得很低。由于Dev sets的目标是用来比较验证不一样算法的优劣,从而选择更好的算法模型就好了。所以,一般不须要全部样本的20%这么多的数据来进行验证。对于100万的样本,每每只须要10000个样原本作验证就够了。Test sets也是同样,目标是测试已选算法的实际表现,无偏估计。对于100万的样本,每每也只须要10000个样本就够了。所以,对于大数据样本,Train/Dev/Test sets的比例一般能够设置为98%/1%/1%,或者99%/0.5%/0.5%。样本数据量越大,相应的Dev/Test sets的比例能够设置的越低一些。

现代深度学习还有个重要的问题就是训练样本和测试样本分布上不匹配,意思是训练样本和测试样原本自于不一样的分布。举个例子,假设你开发一个手机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. 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呢?

例如猫识别问题,输入是一幅图像,其特征维度很大。这种状况下,咱们能够经过两个数值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. Basic Recipe for Machine Learning

机器学习中基本的一个诀窍就是避免出现high bias和high variance。首先,减小high bias的方法一般是增长神经网络的隐藏层个数、神经元个数,训练时间延长,选择其它更复杂的NN模型等。在base error不高的状况下,通常都能经过这些方式有效下降和避免high bias,至少在训练集上表现良好。其次,减小high variance的方法一般是增长训练样本数据,进行正则化Regularization,选择其余更复杂的NN模型等。

这里有几点须要注意的。第一,解决high bias和high variance的方法是不一样的。实际应用中经过Train set error和Dev set error判断是否出现了high bias或者high variance,而后再选择针对性的方法解决问题。

第二,Bias和Variance的折中tradeoff。传统机器学习算法中,Bias和Variance一般是对立的,减少Bias会增长Variance,减少Variance会增长Bias。而在如今的深度学习中,经过使用更复杂的神经网络和海量的训练样本,通常可以同时有效减少Bias和Variance。这也是深度学习之因此如此强大的缘由之一。

4. Regularization

若是出现了过拟合,即high variance,则须要采用正则化regularization来解决。虽然扩大训练样本数量也是减少high variance的一种方法,可是一般得到更多训练样本的成本过高,比较困难。因此,更可行有效的办法就是使用regularization。

咱们先来回顾一下以前介绍的Logistic regression。采用L2 regularization,其表达式为:

J ( w , b ) = 1 m i = 1 m L ( y ^ ( i ) , y ( i ) ) + λ 2 m | | w | | 2 2

| | w | | 2 2 = j = 1 n x w j 2 = w T w

这里有个问题:为何只对w进行正则化而不对b进行正则化呢?其实也能够对b进行正则化。可是通常w的维度很大,而b只是一个常数。相比较来讲,参数很大程度上由w决定,改变b值对总体模型影响较小。因此,通常为了简便,就忽略对b的正则化了。

除了L2 regularization以外,还有另一只正则化方法:L1 regularization。其表达式为:

J ( w , b ) = 1 m i = 1 m L ( y ^ ( i ) , y ( i ) ) + λ 2 m | | w | | 1

| | w | | 1 = j = 1 n x | w j |

与L2 regularization相比,L1 regularization获得的w更加稀疏,即不少w为零值。其优势是节约存储空间,由于大部分w为0。然而,实际上L1 regularization在解决high variance方面比L2 regularization并不更具优点。并且,L1的在微分求导方面比较复杂。因此,通常L2 regularization更加经常使用。

L一、L2 regularization中的 λ 就是正则化参数(超参数的一种)。能够设置 λ 为不一样的值,在Dev set中进行验证,选择最佳的 λ 。顺便提一下,在python中,因为lambda是保留字,因此为了不冲突,咱们使用lambd来表示 λ

在深度学习模型中,L2 regularization的表达式为:

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

| | w [ l ] | | 2 = i = 1 n [ l ] j = 1 n [ l 1 ] ( w i j [ l ] ) 2

一般,咱们把 | | w [ l ] | | 2 称为Frobenius范数,记为 | | w [ l ] | | F 2 。一个矩阵的Frobenius范数就是计算全部元素平方和再开方,以下所示:

| | A | | F = i = 1 m j = 1 n | a i j | 2

值得注意的是,因为加入了正则化项,梯度降低算法中的 d w [ l ] 计算表达式须要作以下修改:

d w [ l ] = d w b e f o r e [ l ] + λ m w [ l ]

w [ l ] := w [ l ] α d w [ l ]

L2 regularization也被称作weight decay。这是由于,因为加上了正则项, d w [ l ] 有个增量,在更新 w [ l ] 的时候,会多减去这个增量,使得 w [ l ] 比没有正则项的值要小一些。不断迭代更新,不断地减少。

(1) w [ l ] := w [ l ] α d w [ l ] (2) = w [ l ] α ( d w b e f o r e [ l ] + λ m w [ l ] ) (3) = ( 1 α λ m ) w [ l ] α d w b e f o r e [ l ]

其中, ( 1 α λ m ) < 1

5. Why regularization reduces overfitting

为何正则化可以有效避免high variance,防止过拟合呢?下面咱们经过几个例子说明。

仍是以前那张图,从左到右,分别表示了欠拟合,恰好拟合,过拟合三种状况。

这里写图片描述

假如咱们选择了很是复杂的神经网络模型,如上图左上角所示。在未使用正则化的状况下,咱们获得的分类超平面多是相似上图右侧的过拟合。可是,若是使用L2 regularization,当 λ 很大时, w [ l ] 0 w [ l ] 近似为零,意味着该神经网络模型中的某些神经元实际的做用很小,能够忽略。从效果上来看,实际上是将某些神经元给忽略掉了。这样本来过于复杂的神经网络模型就变得不那么复杂了,而变得很是简单化了。以下图所示,整个简化的神经网络模型变成了一个逻辑回归模型。问题就从high variance变成了high bias了。

这里写图片描述

所以,选择合适大小的 λ 值,就可以同时避免high bias和high variance,获得最佳模型。

还有另一个直观的例子来解释为何正则化可以避免发生过拟合。假设激活函数是tanh函数。tanh函数的特色是在z接近零的区域,函数近似是线性的,而当|z|很大的时候,函数非线性且变化缓慢。当使用正则化, λ 较大,即对权重 w [ l ] 的惩罚较大, w [ l ] 减少。由于 z [ l ] = w [ l ] a [ l ] + b [ l ] 。当 w [ l ] 减少的时候, z [ l ] 也会减少。则此时的 z [ l ] 分布在tanh函数的近似线性区域。那么这个神经元起的做用就至关因而linear regression。若是每一个神经元对应的权重 w [ l ] 都比较小,那么整个神经网络模型至关因而多个linear regression的组合,便可当作一个linear network。获得的分类超平面就会比较简单,不会出现过拟合现象。

这里写图片描述

6. Dropout Regularization

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

Dropout是指在深度学习网络的训练过程当中,对于每层的神经元,按照必定的几率将其暂时从网络中丢弃。也就是说,每次训练时,每一层都有部分神经元不工做,起到简化复杂网络模型的效果,从而避免发生过拟合。

这里写图片描述

Dropout有不一样的实现方法,接下来介绍一种经常使用的方法:Inverted dropout。假设对于第 l 层神经元,设定保留神经元比例几率keep_prob=0.8,即该层有20%的神经元中止工做。 d l 为dropout向量,设置 d l 为随机vector,其中80%的元素为1,20%的元素为0。在python中可使用以下语句生成dropout vector:

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

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

al = np.multiply(al,dl)

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

al /= keep_prob

以上就是Inverted dropout的方法。之因此要对 a l 进行scale up是为了保证在通过dropout后, a l 做为下一层神经元的输入值尽可能保持不变。假设第 l 层有50个神经元,通过dropout后,有10个神经元中止工做,这样只有40神经元有做用。那么获得的 a l 只至关于原来的80%。scale up后,可以尽量保持 a l 的指望值相比以前没有大的变化。

Inverted dropout的另一个好处就是在对该dropout后的神经网络进行测试时可以减小scaling问题。由于在训练时,使用scale up保证 a l 的指望值没有大的变化,测试时就不须要再对样本数据进行相似的尺度伸缩操做了。

对于m个样本,单次迭代训练时,随机删除掉隐藏层必定数量的神经元;而后,在删除后的剩下的神经元上正向和反向更新权重w和常数项b;接着,下一次迭代中,再恢复以前删除的神经元,从新随机删除必定数量的神经元,进行正向和反向更新w和b。不断重复上述过程,直至迭代训练完成。

值得注意的是,使用dropout训练结束后,在测试和实际应用模型时,不须要进行dropout和随机删减神经元,全部的神经元都在工做。

7. Understanding Dropout

Dropout经过每次迭代训练时,随机选择不一样的神经元,至关于每次都在不一样的神经网络上进行训练,相似机器学习中Bagging的方法(三个臭皮匠,胜过诸葛亮),可以防止过拟合。

除此以外,还能够从权重w的角度来解释为何dropout可以有效防止过拟合。对于某个神经元来讲,某次训练时,它的某些输入在dropout的做用被过滤了。而在下一次训练时,又有不一样的某些输入被过滤。通过屡次训练后,某些输入被过滤,某些输入被保留。这样,该神经元就不会受某个输入很是大的影响,影响被均匀化了。也就是说,对应的权重w不会很大。这从从效果上来讲,与L2 regularization是相似的,都是对权重w进行“惩罚”,减少了w的值。

这里写图片描述

总结一下,对于同一组训练数据,利用不一样的神经网络训练以后,求其输出的平均值能够减小overfitting。Dropout就是利用这个原理,每次丢掉必定数量的隐藏层神经元,至关于在不一样的神经网络上进行训练,这样就减小了神经元之间的依赖性,即每一个神经元不能依赖于某几个其余的神经元(指层与层之间相链接的神经元),使神经网络更加能学习到与其余神经元之间的更加健壮robust的特征。

在使用dropout的时候,有几点须要注意。首先,不一样隐藏层的dropout系数keep_prob能够不一样。通常来讲,神经元越多的隐藏层,keep_out能够设置得小一些.,例如0.5;神经元越少的隐藏层,keep_out能够设置的大一些,例如0.8,设置是1。另外,实际应用中,不建议对输入层进行dropout,若是输入层维度很大,例如图片,那么能够设置dropout,但keep_out应设置的大一些,例如0.8,0.9。整体来讲,就是越容易出现overfitting的隐藏层,其keep_prob就设置的相对小一些。没有准确固定的作法,一般能够根据validation进行选择。

Dropout在电脑视觉CV领域应用比较普遍,由于输入层维度较大,并且没有足够多的样本数量。值得注意的是dropout是一种regularization技巧,用来防止过拟合的,最好只在须要regularization的时候使用dropout。

使用dropout的时候,能够经过绘制cost function来进行debug,看看dropout是否正确执行。通常作法是,将全部层的keep_prob全设置为1,再绘制cost function,即涵盖全部神经元,看J是否单调降低。下一次迭代训练时,再将keep_prob设置为其它值。

8. Other regularization methods

除了L2 regularization和dropout regularization以外,还有其它减小过拟合的方法。

一种方法是增长训练样本数量。可是一般成本较高,难以得到额外的训练样本。可是,咱们能够对已有的训练样本进行一些处理来“制造”出更多的样本,称为data augmentation。例如图片识别问题中,能够对已有的图片进行水平翻转、垂直翻转、任意角度旋转、缩放或扩大等等。以下图所示,这些处理都能“制造”出新的训练样本。虽然这些是基于原有样本的,可是对增大训练样本数量仍是有颇有帮助的,不须要增长额外成本,却能起到防止过拟合的效果。

这里写图片描述

在数字识别中,也能够将原有的数字图片进行任意旋转或者扭曲,或者增长一些noise,以下图所示:

这里写图片描述

还有另一种防止过拟合的方法: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更加经常使用一些。

9. Normalizing inputs

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

μ = 1 m i = 1 m X ( i )

σ 2 = 1 m i = 1 m ( X ( i ) ) 2

X := X μ σ 2

以二维平面为例,下图展现了其归一化过程:

这里写图片描述

值得注意的是,因为训练集进行了标准化处理,那么对于测试集或在实际应用时,应该使用一样的 μ σ 2 对其进行标准化处理。这样保证了训练集合测试集的标准化操做一致。

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

然而,若是进行了标准化操做,x1与x2分布均匀,w1和w2数值差异不大,获得的cost function与w和b的关系是相似圆形碗。对其进行梯度降低算法时, α 能够选择相对大一些,且J通常不会发生振荡,保证了J是单调降低的。以下右图所示。

这里写图片描述

另一种状况,若是输入特征之间的范围原本就比较接近,那么不进行标准化操做也是没有太大影响的。可是,标准化处理在大多数场合下仍是值得推荐的。

10. Vanishing and Exploding gradients

在神经网络尤为是深度神经网络中存在可能存在这样一个问题:梯度消失和梯度爆炸。意思是当训练一个 层数很是多的神经网络时,计算获得的梯度可能很是小或很是大,甚至是指数级别的减少或增大。这样会让训练过程变得很是困难。

举个例子来讲明,假设一个多层的每层只包含两个神经元的深度神经网络模型,以下图所示:

这里写图片描述

为了简化复杂度,便于分析,咱们令各层的激活函数为线性函数,即 g ( Z ) = Z 。且忽略各层常数项b的影响,令b所有为零。那么,该网络的预测输出 Y ^ 为:

Y ^ = W [ L ] W [ L 1 ] W [ L 2 ] W [ 3 ] W [ 2 ] W [ 1 ] X

若是各层权重 W [ l ] 的元素都稍大于1,例如1.5,则预测输出 Y ^ 将正比于 1.5 L 。L越大, Y ^ 越大,且呈指数型增加。咱们称之为数值爆炸。相反,若是各层权重 W [ l ] 的元素都稍小于1,例如0.5,则预测输出 Y ^ 将正比于 0.5 L 。网络层数L越多, Y ^ 呈指数型减少。咱们称之为数值消失。

也就是说,若是各层权重 W [ l ] 都大于1或者都小于1,那么各层激活函数的输出将随着层数 l 的增长,呈指数型增大或减少。当层数很大时,出现数值爆炸或消失。一样,这种状况也会引发梯度呈现一样的指数型增大或减少的变化。L很是大时,例如L=150,则梯度会很是大或很是小,引发每次更新的步进长度过大或者太小,这让训练过程十分困难。

11. Weight Initialization for Deep Networks

下面介绍如何改善Vanishing and Exploding gradients这类问题,方法是对权重w进行一些初始化处理。

深度神经网络模型中,以单个神经元为例,该层( l )的输入个数为n,其输出为:

z = w 1 x 1 + w 2 x 2 + + w n x n

a = g ( z )

这里写图片描述

这里忽略了常数项b。为了让z不会过大或者太小,思路是让w与n有关,且n越大,w应该越小才好。这样可以保证z不会过大。一种方法是在初始化w时,令其方差为 1 n 。相应的python伪代码为:

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

若是激活函数是tanh,通常选择上面的初始化方法。

若是激活函数是ReLU,权重w的初始化通常令其方差为 2 n

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

除此以外,Yoshua Bengio提出了另一种初始化w的方法,令其方差为 2 n [ l 1 ] n [ l ]

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

至于选择哪一种初始化方法因人而异,能够根据不一样的激活函数选择不一样方法。另外,咱们能够对这些初始化方法中设置某些参数,做为超参数,经过验证集进行验证,获得最优参数,来优化神经网络。

12. Numerical approximation of gradients

Back Propagation神经网络有一项重要的测试是梯度检查(gradient checking)。其目的是检查验证反向传播过程当中梯度降低算法是否正确。该小节将先介绍如何近似求出梯度值。

这里写图片描述

利用微分思想,函数f在点 θ 处的梯度能够表示成:

g ( θ ) = f ( θ + ε ) f ( θ ε ) 2 ε

其中, ε > 0 ,且足够小。

13. Gradient checking

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

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

而后将反向传播过程经过梯度降低算法获得的 d W [ 1 ] , d b [ 1 ] , , d W [ L ] , d b [ L ] 按照同样的顺序构形成一个一维向量 d θ d θ 的维度与 θ 一致。

接着利用 J ( θ ) 对每一个 θ i 计算近似梯度,其值与反向传播算法获得的 d θ i 相比较,检查是否一致。例如,对于第i个元素,近似梯度为:

d θ a p p r o x [ i ] = J ( θ 1 , θ 2 , , θ i + ε , ) J ( θ 1 , θ 2 , , θ i ε , ) 2 ε

计算完全部 θ i 的近似梯度后,能够计算 d θ a p p r o x d θ 的欧氏(Euclidean)距离来比较两者的类似度。公式以下:

| | d θ a p p r o x d θ | | 2 | | d θ a p p r o x | | 2 + | | d θ | | 2

通常来讲,若是欧氏距离越小,例如 10 7 ,甚至更小,则代表 d θ a p p r o x d θ 越接近,即反向梯度计算是正确的,没有bugs。若是欧氏距离较大,例如 10 5 ,则代表梯度计算可能出现问题,须要再次检查是否有bugs存在。若是欧氏距离很大,例如 10 3 ,甚至更大,则代表 d θ a p p r o x d θ 差异很大,梯度降低计算过程有bugs,须要仔细检查。

14. Gradient Checking Implementation Notes

在进行梯度检查的过程当中有几点须要注意的地方:

  • 不要在整个训练过程当中都进行梯度检查,仅仅做为debug使用。

  • 若是梯度检查出现错误,找到对应出错的梯度,检查其推导是否出现错误。

  • 注意不要忽略正则化项,计算近似梯度的时候要包括进去。

  • 梯度检查时关闭dropout,检查完毕后再打开dropout。

  • 随机初始化时运行梯度检查,通过一些训练后再进行梯度检查(不经常使用)。

更多AI资源请关注公众号:红色石头的机器学习之路(ID:redstonewill)
这里写图片描述