吴恩达改善深层神经网络章节笔记(一)——正则化和梯度相关知识


视频课程链接:
https://www.bilibili.com/video/BV1FT4y1E74V?
笔记参考链接:
https://blog.csdn.net/weixin_36815313/article/details/105728919

1. 训练/开发/测试集 (Train/Dev/Test Sets)

训练神经网络时,我们需要做出很多决策,例如:

  • 神经网络分多少层
  • 每层含有多少个隐藏单元
  • 学习速率是多少
  • 各层采用哪些激活函数

创建新应用的过程中,我们不可能从一开始就准确预测出这些信息和其他的超参数。实际上,应用型机器学习是一个高度迭代的过程,通常在项目启动时,我们会先有一个初步想法,比如构建一个含有特定层数,隐藏单元数量或数据集个数等等的神经网络,然后编码,并尝试运行这些代码,通过运行和测试得到该神经网络或这些配置信息的运行结果,你可以根据输出结果重新完善自己的想法,改变策略,或者为了找到更好的神经网络不断迭代更新自己的方案。
在这里插入图片描述

所以说,应用深度学习是一个典型的迭代过程,需要多次循环往复,才能为应用程序找到一个称心的神经网络,因此循环该过程的效率是决定项目进展速度的一个关键因素,而创建高质量的训练数据集,验证集和测试集也有助于提高循环效率。
在这里插入图片描述

假设这是训练数据,我用一个长方形表示,我们通常会将这些数据划分成几部分,一部分作为训练集(train set),一部分作为简单交叉验证集,方便起见,就叫它验证集(dev set),最后一部分则作为测试集(test set)
接下来,我们开始对训练集执行训练算法,通过验证集或简单交叉验证集选择最好的模型,经过充分验证,我们选定了最终模型,然后就可以在测试集上进行评估了,为了无偏评估算法的运行状况。
在机器学习发展的小数据量时代,常见做法是将所有数据三七分,就是人们常说的70%验证集,30%测试集。如果没有明确设置验证集,也可以按照60%训练集,20%验证集和20%测试集来划分。这是前几年机器学习领域普遍认可的最好的实践方法。
但是在大数据时代,我们现在的数据量可能是百万级别,那么验证集和测试集占数据总量的比例会趋向于变得更小。因为验证集的目的就是验证不同的算法,检验哪种算法更有效,因此验证集要足够大才能评估,比如有2个甚至10个不同算法,并迅速判断出哪种算法更有效。我们可能不需要拿出20%的数据作为验证集,比如我们有100万条数据,那么取1万条数据便足以进行评估,找出其中表现最好的1~2种算法。同样地,根据最终选择的分类器,测试集的主要目的是正确评估分类器的性能,所以如果拥有百万数据,我们只需要1000条数据,便足以评估单个分类器,并且准确评估该分类器的性能。假设我们有100万条数据,其中1万条作为验证集,1万条作为测试集,100万里取1万,比例是1%,即训练集占98%,验证集和测试集各占1%。对于数据量过百万的应用,训练集可以占到99.5%,验证和测试集各占0.25%,或者验证集占0.4%,测试集占0.1%。
现代深度学习的另一个趋势是越来越多的人在训练和测试集分布不匹配的情况下进行训练。假设你要构建一个用户可以上传大量图片的应用程序,目的是找出并呈现所有猫咪图片,训练集可能是从网上下载的猫咪图片,而验证集和测试集是用户在这个应用上上传的猫的图片,结果许多网页上的猫咪图片分辨率很高,后期制作精良,而用户上传的照片可能是用手机随意拍摄的,像素低,比较模糊,这两类数据有所不同。针对这种情况,要确保验证集和测试集的数据来自同一分布
但由于深度学习算法需要大量的训练数据,为了获取更大规模的训练数据集,我们可以采用当前流行的各种创意策略,例如网页抓取,代价就是训练集数据与验证集和测试集数据有可能不是来自同一分布。但只要遵循这个经验法则,你就会发现机器学习算法会变得更快。
最后一点,就算没有测试集也不要紧,测试集的目的是对最终所选定的神经网络系统做出无偏估计,如果不需要无偏估计,也可以不设置测试集。所以如果只有验证集,没有测试集,我们要做的就是在训练集上训练,尝试不同的模型框架,在验证集上评估这些模型,然后迭代并选出适用的模型。因为验证集中已经涵盖测试集数据,其不再提供无偏性能评估。当然,如果你不需要无偏估计,那就再好不过了。
所以,搭建训练验证集和测试集能够加速神经网络的集成,也可以更有效地衡量算法的偏差和方差,从而帮助我们更高效地选择合适的方法来优化算法。

2. 偏差/方差 (Bias/Variance)

在这里插入图片描述

假设这是数据集,如果给这个数据集拟合一条直线,可能得到一个逻辑回归拟合,但它并不能很好地拟合该数据,这属于高偏差(high bias),我们称为欠拟合(underfitting)
在这里插入图片描述

相反的,如果我们想拟合一个非常复杂的分类器,比如深度神经网络或含有隐藏单元的神经网络,可能就非常适用于这个数据集,但是这看起来也不是一种很好的拟合方式,分类器方差较高(high variance),数据过拟合(overfitting)
在这里插入图片描述

在两者之间,可能还有一些像图中这样,复杂程度适中,数据拟合适度的分类器,这个数据拟合看起来更加合理,我们称之为适度拟合(just right),是介于过拟合和欠拟合中间的一类。
在上述这样一个只有 x 1 x_1 x1 x 2 x_2 x2两个特征的二维数据集中,我们可以绘制数据,将偏差和方差可视化。在多维空间数据中,绘制数据和可视化分割边界无法实现,但我们可以通过几个指标,来研究偏差和方差。
偏差和方差的两个关键数据是训练集误差(Train set error)验证集误差(Dev set error)
① 假定训练集误差是1%验证集误差是11%,可以看出训练集设置得非常好,而验证集设置相对较差,我们可能过度拟合了训练集,在某种程度上,验证集并没有充分利用交叉验证集的作用,像这种情况,我们称之为高方差(high variance)。
② 假定训练集误差是15%验证集误差是16%,算法并没有在训练集中得到很好训练,如果训练数据的拟合度不高,即数据欠拟合,就可以说这种算法偏差比较高(high bias)。相反,它对于验证集产生的结果却是合理的,验证集中的错误率只比训练集的多了1%,所以这种算法偏差高(high bias),因为它甚至不能拟合训练集。
③ 假定训练集误差是15%验证集误差是30%,训练集的偏差相当高,但是验证集的评估结果更糟糕,在这种情况下,我们会认为这种算法偏差高(high bias),因为它在训练集上结果不理想,而且方差也很高(high variance),这是方差和偏差都很糟糕的情况。
④ 假定训练集误差是0.5%验证集误差是1%,这样的结果是相当好的,分类器只有1%的错误率,偏差和方差都很低。
以上分析的前提都是假设基本误差很小,且最优误差接近0%,训练集和验证集数据来自相同分布。
在这里插入图片描述

上图这样的分类器会产生高偏差(high bias),因为它的数据拟合度低,像这种接近线性的分类器,数据拟合度低。
在这里插入图片描述

我们稍微改变一下分类器(紫色部分),这条曲线中间部分灵活性非常高,却过度拟合了部分数据,该分类器具有高偏差(high bias)和高方差(high variance),其中偏差高(high bias)是因为它几乎是一条线性分类器,并未拟合数据。
在这里插入图片描述

上述这种二次曲线(蓝色虚线)能够很好地拟合数据。但是采用曲线函数或二次函数会产生高方差(high variance),因为曲线灵活性太高,导致拟合了这两个错误样本和中间这些活跃数据。
这从两个维度上看起来不太自然,但对于高维数据,有些数据区域偏差高,有些数据区域方差高,所以在高维数据中采用这种分类器看起来就不会那么牵强了。

3. 机器学习基础 (Basic Recipe for Machine Learning)

训练神经网络用到的基本方法及流程:
在这里插入图片描述

有两点需要大家注意:
第一点,高偏差和高方差是两种不同的情况,我们后续要尝试的方法也可能完全不同,我通常会用训练验证集来诊断算法是否存在偏差或方差问题,然后根据结果选择尝试部分方法。举个例子,如果算法存在高偏差问题,准备更多训练数据其实也没什么用处,至少这不是更有效的方法,所以大家要清楚存在的问题是偏差还是方差,还是两者都有问题,明确这一点有助于我们选择出最有效的方法。
第二点,在机器学习的初期阶段,关于所谓的偏差方差权衡的讨论屡见不鲜,原因是我们能尝试的方法有很多,可以增大偏差和减小方差,也可以减小偏差和增大方差,但是在深度学习的早期阶段,我们没有太多工具可以做到只减小偏差或方差却不影响到另一方。在当前的深度学习和大数据时代,只要持续训练一个更大的网络,只要准备了更多数据,那么并非只有这两种情况。我们假定是这样,那么只要正则适度,通常构建一个更大的网络便可以在不影响方差的同时减少偏差,而采用更多数据通常可以在不过多影响偏差的同时减小方差。这两步实际要做的工作是训练网络,选择网络或者准备更多数据,现在我们有工具可以做到在减小偏差或方差的同时,不对另一方产生过多不良影响。这就是深度学习对监督学习大有裨益的一个重要原因,也是我们不用太过关注如何平衡偏差和方差的一个重要原因,但有时我们有很多的选择来减少偏差或方差而不影响另一方。最终,我们会得到一个非常规范化的网络。

4. 正则化 (Regularization)

神经网络可能存在过度拟合数据的问题,即高方差问题,通常有两种解决方法,一个是正则化,另一个是准备更多的数据,但你可能无法准备足够多的训练数据,或者获取更多数据的成本很高,而正则化通常有助于避免过度拟合,或者减少网络误差。

4.1 逻辑回归中的正则化

从逻辑回归上来说, J ( w , b ) J(w,b) J(w,b)是我们定义的代价函数,参数包含一些训练数据和不同数据中个体预测的损失, w w w b b b是逻辑回归的两个参数。在逻辑回归函数中加入正则化,只需添加正则化参数 λ λ λ
J ( w , b ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) + λ 2 m Ω ( w ) J(w,b)=\frac{1}{m}\sum_{i=1}^{m}L(\hat{y}^{(i)},y^{(i)})+\frac{\lambda}{2m} Ω(w) J(w,b)=m1i=1mL(y^(i),y(i))+2mλΩ(w)因为 w w w通常是一个高维参数矢量,已经可以表达高偏差问题, w w w可能包含有很多参数,我们不可能拟合所有参数,而 b b b只是单个数字,如果加了参数 b b b,其实也没太大影响,因为 b b b只是众多参数中的一个,所以通常省略不计。
L 1 L1 L1正则化: Ω ( w ) = ∣ ∣ w ∣ ∣ 1 = ∑ j = 1 n x ∣ w j ∣ Ω(w)=||w||_1=\sum_{j=1}^{n_x}|w_j| Ω(w)=w1=j=1nxwj L 1 L1 L1正则化会使模型变得稀疏,却没有降低太多存储内存,所以人们在训练网络时,越来越倾向于使用 L 2 L2 L2正则化。
L 2 L2 L2正则化: Ω ( w ) = ∣ ∣ w ∣ ∣ 2 2 = ∑ j = 1 n x w j 2 = w T w Ω(w)=||w||^2_2=\sum_{j=1}^{n_x}w^2_j=w^Tw Ω(w)=w22=j=1nxwj2=wTw我们通常使用验证集或交叉验证集来配置参数 λ λ λ,尝试各种各样的数据,寻找最好的参数。我们要考虑训练集之间的权衡,把参数设置为较小值,这样可以避免过拟合。

4.2 神经网络中的正则化

在神经网络中定义一个成本函数 J J J,该函数包含 W [ l ] W^{[l]} W[l] b [ l ] b^{[l]} b[l] W [ L ] W^{[L]} W[L] b [ L ] b^{[L]} b[L]的所有参数,字母 L L L是神经网络所含的层数。 J ( W [ l ] , b [ l ] , … , W [ L ] , b [ L ] ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) + λ 2 m ∑ l = 1 L ∣ ∣ W [ l ] ∣ ∣ F 2 J(W^{[l]},b^{[l]},…,W^{[L]},b^{[L]})=\frac{1}{m}\sum_{i=1}^{m}L(\hat{y}^{(i)},y^{(i)})+\frac{\lambda}{2m} \sum_{l=1}^{L}||W^{[l]}||^2_F J(W[l],b[l],,W[L],b[L])=m1i=1mL(y^(i),y(i))+2mλl=1LW[l]F2其中 W W W是一个 n [ l ] × n [ l − 1 ] n^{[l]}\times n^{[l-1]} n[l]×n[l1]的多维矩阵(这里 W W W的维度是没有转置的), n [ l ] n^{[l]} n[l]表示第 l l l层单元的数量, n [ l − 1 ] n^{[l-1]} n[l1]表示第 l − 1 l-1 l1层隐藏单元的数量。 ∣ ∣ W [ l ] ∣ ∣ = ∑ i = 1 n [ l ] ∑ j = 1 n [ l − 1 ] ( W i j [ l ] ) 2 ||W^{[l]}||=\sum_{i=1}^{n^{[l]}}\sum_{j=1}^{n^{[l-1]}}(W^{[l]}_{ij})^2 W[l]=i=1n[l]j=1n[l1](Wij[l])2该矩阵范数被称作弗罗贝尼乌斯范数,用下标 F F F标注,它表示一个矩阵中所有元素的平方和。

4.3 使用范数实现梯度下降

在神经网络中实现梯度下降的方法是,使用反向传播(backprop)计算出 d w [ l ] dw^{[l]} dw[l]的值,即 J J J W [ l ] W^{[l]} W[l]的偏导数,并通过公式 W [ l ] = W [ l ] − α d W [ l ] W^{[l]}=W^{[l]}-\alpha dW^{[l]} W[l]=W[l]αdW[l]更新 W [ l ] W^{[l]} W[l]
而现在代价函数 J J J增加了额外的正则化项 λ m Ω ( W ) \frac{\lambda}{m} Ω(W) mλΩ(W),因此我们要做的就是给 d W [ l ] dW^{[l]} dW[l]加上这一项 λ m W [ l ] \frac {\lambda}{m}W^{[l]} mλW[l],然后计算这个更新项。 d W [ l ] = ( d W [ l ]   f r o m   b a c k p r o p ) + λ m W [ l ] (1) dW^{[l]}=(dW^{[l]}\ from\ backprop)+\frac{\lambda}{m}W^{[l]} \tag1 dW[l]=(dW[l] from backprop)+mλW[l](1) W [ l ] = W [ l ] − α d W [ l ] (2) W^{[l]}=W^{[l]}-\alpha dW^{[l]} \tag2 W[l]=W[l]αdW[l](2)将公式(1)代入到公式(2)中的 d W [ l ] dW^{[l]} dW[l],可以得到 W [ l ] = W [ l ] − α [ ( d W [ l ]   f r o m   b a c k p r o p ) + λ m W [ l ] ] = W [ l ] − α λ m W [ l ] − α ( d W [ l ]   f r o m   b a c k p r o p ) = W [ l ] ⋅ ( 1 − α λ m ) − α ( d W [ l ]   f r o m   b a c k p r o p ) \begin{aligned} W^{[l]}&=W^{[l]}-\alpha [(dW^{[l]}\ from\ backprop)+\frac{\lambda}{m}W^{[l]}] \\ &=W^{[l]}-\frac{\alpha \lambda}{m}W^{[l]}-\alpha (dW^{[l]}\ from\ backprop) \\ &=W^{[l]}\cdot (1-\frac{\alpha \lambda}{m})-\alpha (dW^{[l]}\ from\ backprop) \\ \end{aligned} W[l]=W[l]α[(dW[l] from backprop)+mλW[l]]=W[l]mαλW[l]α(dW[l] from backprop)=W[l](1mαλ)α(dW[l] from backprop)从上面的正则项可以看出,不论 W [ l ] W^{[l]} W[l]是什么,我们都在试图让它变得更小,相当于矩阵 W [ l ] W^{[l]} W[l]乘以一个系数 ( 1 − α λ m ) (1−\alpha \frac{\lambda}{m}) (1αmλ),该系数小于1,因此 L 2 L2 L2正则化也被称为权重衰减。

5. 为什么正则化有利于预防过拟合? (Why regularization reduces overfitting?)

5.1 案例一

在这里插入图片描述

假设这是一个过拟合的深层神经网络。对代价函数 J J J添加正则项,它可以避免数据权值矩阵过大。直观上理解就是,如果正则化系数 λ \lambda λ设置得足够大,权重矩阵 W W W接近于0,于是基本上消除了这些隐藏单元的影响,我们直觉上认为大量隐藏单元被完全消除了,其实不然,实际上是该神经网络的所有隐藏单元依然存在,但是它们的影响变得更小了。这个被大大简化了的神经网络会变成一个很小的网络,小到如同一个逻辑回归单元,但是深度却很大,它会使这个网络从过拟合的状态接近高偏差状态。但是正则化系数 λ \lambda λ会存在一个中间值,使得这个网络会有一个接近Just Right的中间状态。在这里插入图片描述

5.2 案例二

在这里插入图片描述

假设我们用双曲正切函数 g ( z ) = t a n h ( z ) g(z)=tanh(z) g(z)=tanh(z)作为激活函数。 W [ l ] = W [ l ] ⋅ ( 1 − α λ m ) − α ( d W [ l ]   f r o m   b a c k p r o p ) W^{[l]}=W^{[l]}\cdot (1-\frac{\alpha \lambda}{m})-\alpha (dW^{[l]}\ from\ backprop) W[l]=W[l](1mαλ)α(dW[l] from backprop) z [ l ] = W [ l ] z [ l ] + b [ l ] z^{[l]}=W^{[l]}z^{[l]}+b^{[l]} z[l]=W[l]z[l]+b[l]由以上两个公式可知,如果正则化参数 λ \lambda λ变得很大,参数 W W W则会变得很小, z z z也会相对变小(忽略 b b b的影响)。
在这里插入图片描述

如果 z z z的取值在这个范围内,即 z z z取得相对较小的值,此时 g ( z ) g(z) g(z)大致呈线性函数。在第一课为什么需要非线性激活函数?中提到,如果每一层都是线性的,那么整个神经网络就是一个线性网络,即使是一个非常深的深层网络,因其具有线性激活函数的特征,我们只能计算线性函数,因此它不适用于非常复杂的决策,以及过度拟合数据集的非线性决策边界。这样的线性函数非常简单,通常不会发生过拟合。

6. Dropout正则化 (Dropout regularization)

6.1 工作原理

除了 L 2 L2 L2正则化,还有一个非常实用的正则化方法——Dropout(随机失活)
在这里插入图片描述

假设训练上图这样的神经网络,它存在过拟合问题。Dropout会遍历网络的每一层,并设置消除神经网络中节点的概率。假设网络中的每一层、每一个节点都以抛硬币的方式设置概率,即每个节点得以保留和消除的概率都是0.5。
在这里插入图片描述

设置完节点概率,我们会消除一些节点,然后删除掉从该节点进出的连线,最后得到一个节点更少,规模更小的网络,然后用反向传播(backprop)方法进行训练。
在这里插入图片描述

6.2 反向随机失活 (Inverted Dropout)

我们用一个三层(L=3)神经网络来举例说明,这里只举例说明如何在某一层中实施Dropout。
首先定义向量 d d d d [ 3 ] d^{[3]} d[3]表示一个三层的Dropout向量:

d3 = np.random.rand(a3.shape[0],a3.shape[1]) < keep_prob

然后看它是否小于某数,我们称之为keep-probkeep-prob是一个具体数字,上个示例中它是0.5,而本例中它是0.8。它表示保留某个隐藏单元的概率为0.8,也意味着消除任意一个隐藏单元的概率是0.2,它的作用就是生成一个随机矩阵。而 d [ 3 ] d^{[3]} d[3]就是这样一个矩阵,其中的对应值为1的概率都是0.8,对应为0的概率是0.2。
接下来要做的就是从第三层中获取激活函数,这里我们叫它 a [ 3 ] a^{[3]} a[3] a [ 3 ] a^{[3]} a[3]含有要计算的激活函数, a [ 3 ] a^{[3]} a[3]等于上面的 a [ 3 ] a^{[3]} a[3]乘以 d [ 3 ] d^{[3]} d[3]

a3 = np.multiply(a3,d3)

这里是元素相乘,因此也可写为

a3 *= d3

它的作用就是让 d [ 3 ] d^{[3]} d[3]中所有等于0的元素,与 a [ 3 ] a^{[3]} a[3]中相对应的元素进行乘法运算并输出,而 d [ 3 ] d^{[3]} d[3]中各个元素等于0的概率只有20%,即让矩阵 a [ 3 ] a^{[3]} a[3]中与矩阵 d [ 3 ] d^{[3]} d[3]中0元素相对应的元素归零。
最后我们向外扩展 a [ 3 ] a^{[3]} a[3],用它除以keep-prob参数。

a3 /= keep-prob

我们假设在第三个隐藏层上有50个单元或50个神经元,在一维上 a [ 3 ] a^{[3]} a[3]的维度是50×1,我们通过因子分解将它拆分成50×m维的,保留和删除它们的概率分别为80%和20%,这意味着最后被删除或归零的单元平均有50×20%=10个。
现在我们看下 z [ 4 ] z^{[4]} z[4] z [ 4 ] = w [ 4 ] a [ 3 ] + b [ 4 ] z^{[4]}=w^{[4]}a^{[3]}+b^{[4]} z[4]=w[4]a[3]+b[4]我们的预期是 a [ 3 ] a^{[3]} a[3]中有20%的元素被归零,为了不影响 z [ 4 ] z^{[4]} z[4]的期望值,我们需要用 w [ 4 ] ∗ a [ 3 ] / 0.8 w^{[4]}*a^{[3]}/0.8 w[4]a[3]/0.8 ,它将会修正或弥补我们所需的那20%,使得 a [ 3 ] a^{[3]} a[3]的期望值不变。

6.3 在测试阶段训练算法

以第0层的激活函数 a [ 0 ] a^{[0]} a[0]作为测试样本 x x x,我们在测试阶段不使用dropout函数,尤其是像下列情况:
z [ 1 ] = w [ 1 ] a [ 0 ] + b [ 1 ] z^{[1]}=w^{[1]}a^{[0]}+b^{[1]} z[1]=w[1]a[0]+b[1] a [ 1 ] = g [ 1 ] ( z [ 1 ] ) a^{[1]}=g^{[1]}(z^{[1]}) a[1]=g[1](z[1]) z [ 2 ] = w [ 2 ] a [ 1 ] + b [ 2 ] z^{[2]}=w^{[2]}a^{[1]}+b^{[2]} z[2]=w[2]a[1]+b[2] a [ 2 ] = g [ 2 ] ( z [ 2 ] ) a^{[2]}=g^{[2]}(z^{[2]}) a[2]=g[2](z[2]) ⋮ \vdots y ^ = a [ L ] = g [ L ] ( z [ L ] ) \hat{y}=a^{[L]}=g^{[L]}(z^{[L]}) y^=a[L]=g[L](z[L])以此类推,直到最后一层,预测值为 y ^ \hat{y} y^
在测试阶段,我们并未使用dropout,自然也就不用抛硬币的方式来决定失活概率,以及要消除哪些隐藏单元了,因为在测试阶段进行预测时,我们不期望输出结果是随机的,如果测试阶段应用dropout函数,预测会受到干扰。理论上,你只需要多次运行预测处理过程,每一次不同的隐藏单元会被随机归零,预测处理遍历它们,但计算效率低,得出的结果也几乎相同,与这个不同程序产生的结果极为相似。
Inverted Dropout函数在除以keep-prob时可以记住上一步的操作,目的是确保即使在测试阶段不执行dropout来调整数值范围,激活函数的预期结果也不会发生变化,所以没必要在测试阶段额外添加尺度参数,这与训练阶段不同。

7. 理解dropout (Understanding Dropout)

Dropout可以随机删除网络中的神经单元,他为什么可以通过正则化发挥如此大的作用呢?
在这里插入图片描述
从单个神经元入手,这个单元的工作就是输入并生成一些有意义的输出。通过dropout,该单元的输入几乎被消除,也就是说这个单元,它不能依靠任何特征,因为特征都有可能被随机清除,或者说该单元的输入都有可能被随机清除。我不愿意把所有赌注都放在一个节点上,不愿意给任何一个输入加上太多权重,因为它可能会被删除,因此该单元通过这种方式传播下去,并为单元的四个输入增加一点权重,通过传播所有权重,dropout将产生收缩权重的平方范数的效果,和之前讲的 L 2 L2 L2正则化类似。实施dropout的结果是它会压缩权重,并完成一些预防过拟合的外层正则化。
dropout被作为一种正则化的替代形式, L 2 L2 L2正则化对不同权重的衰减是不同的,它取决于倍增的激活函数的大小。
在这里插入图片描述

上图是一个拥有三个输入特征的神经网络,其中一个要选择的参数是keep-prob,它代表每一层上保留单元的概率,不同层的keep-prob也可以变化。
第一层权重矩阵 w [ 1 ] w^{[1]} w[1]的维度是7×3,第二层权重矩阵 w [ 2 ] w^{[2]} w[2]的维度是7×7,第三层权重矩阵 w [ 3 ] w^{[3]} w[3]的维度是3×7,其中 w [ 2 ] w^{[2]} w[2]是最大的权重矩阵,因为 w [ 2 ] w^{[2]} w[2]拥有最大的参数集,即7×7,为了预防矩阵的过拟合,对于这一层,它的keep-prob值应该相对较低,假设是0.5。对于其它层,过拟合的程度可能没那么严重,它们的keep-prob值可能高一些,假设是0.7。如果在某一层,我们不必担心其过拟合的问题,那么keep-prob可以设置为1。keep-prob的值是1,意味着保留所有单元,并且不在这一层使用dropout。从技术上讲,我们也可以对输入层应用dropout,我们有机会删除一个或多个输入特征,虽然现实中我们通常不这么做。
实施dropout的两个技巧:
1.计算视觉中的输入量非常大,需要输入太多像素,以至于没有足够的数据,所以dropout在计算机视觉中应用得比较频繁,有些计算机视觉研究人员非常喜欢用它,几乎成了默认的选择,但要牢记一点,dropout是一种正则化方法,它有助于预防过拟合,因此除非算法过拟合,不然是不会使用dropout的,所以它在其它领域应用得比较少,主要存在于计算机视觉领域。
2.dropout一大缺点就是代价函数 J J J不再被明确定义,每次迭代都会随机移除一些节点,如果检查梯度下降的性能,实际上是很难进行复查的,或者说在某种程度上很难计算,所以我们失去了调试工具来绘制图片,而定义明确的代价函数 J J J每次迭代后都会下降。因此通常的做法是先关闭dropout函数,将keep-prob的值设为1,运行代码,确保代价函数 J J J单调递减,然后再打开dropout函数
在这里插入图片描述

8. 其他正则化方法 (Other Regularization Methods)

8.1 数据扩增

假设你正在拟合猫咪图片分类器,如果你想通过扩增训练数据来解决过拟合,但扩增数据代价高,而且有时候我们无法扩增数据,但我们可以通过添加这类图片来增加训练集。
在这里插入图片描述

水平镜像


在这里插入图片描述

裁剪放大

对于光学字符识别,我们还可以通过添加数字,随意旋转或扭曲数字来扩增数据。
在这里插入图片描述

旋转扭曲

通过随意镜像、翻转、扭曲和裁剪图片,我们可以增大数据集,额外生成假训练数据,和全新、独立的猫咪图片数据相比,这些额外的假数据无法像全新数据包含那么多的信息,但我们这么做基本没有花费,代价几乎为零,除了一些对抗性代价。以这种方式来扩增算法数据,进而正则化数据集,减少过拟合会比较廉价。

8.2 early stopping

在这里插入图片描述

运行梯度下降时,我们可以绘制训练误差,或绘制代价函数 J J J的优化过程,在训练集上用0-1记录分类误差次数,呈单调下降趋势。
因为在训练过程中,我们希望训练误差或代价函数 J J J都在下降,通过early stopping,我们还可以绘制验证集误差(dev set error),它可以是验证集上的分类误差,或是验证集上的代价函数、逻辑损失和对数损失等。你会发现,验证集误差(dev set error)通常会先呈下降趋势,然后在某个节点处开始上升。
当你还未在神经网络上运行太多迭代过程的时候,参数 w w w接近0,因为随机初始化 w w w值时,它的值可能都是较小的随机值,所以在你长期训练神经网络之前 w w w依然很小,在迭代过程和训练过程中 w w w的值会变得越来越大,比如在这儿,神经网络中参数 w w w的值已经非常大了,所以early stopping要做的就是在中间点停止迭代过程,此时得到一个 w w w值中等大小的弗罗贝尼乌斯范数 ∣ ∣ w ∣ ∣ F 2 ||w||^2_F wF2,与 L 2 L2 L2正则化相似,选择 ∣ ∣ w ∣ ∣ F 2 ||w||^2_F wF2范数较小的神经网络。
在这里插入图片描述

在机器学习中,超参数激增,选出可行的算法也变得越来越复杂。如果我们用一组工具优化代价函数 J J J,机器学习就会变得更简单,在重点优化代价函数 J J J时,你只需要留意参数 w w w b b b,想办法减小 J ( w , b ) J(w,b) J(w,b)的值,其它的不用关注。预防过拟合还有其他任务,换句话说就是减少方差,这一步我们用另外一套工具来实现,这个原理有时被称为正交化(Orthogonalization),思路就是在一个时间做一个任务early stopping的主要缺点是不能独立地处理这两个问题,因为提早停止梯度下降,也就是停止了优化代价函数 J J J,此时由于你不再尝试降低代价函数 J J J,代价函数 J J J的值可能不够小,同时你又希望不出现过拟合,你没有采取不同的方式来解决这两个问题,而是用一种方法同时解决两个问题,这样做的结果就是你需要考虑的东西变得更复杂。
如果不用early stopping,另一种方法就是 L 2 L2 L2正则化,但训练神经网络的时间可能很长,这会导致超参数搜索空间更容易分解,也更容易搜索,而缺点在于你必须尝试很多正则化参数 λ \lambda λ的值,这也导致在搜索大量 λ \lambda λ值时花费的计算代价太高。与 L 2 L2 L2正则化相比,early stopping的优点是,只运行一次梯度下降就可以找出 w \pmb{w} www的较小值、中间值和较大值,而无需大量尝试 L 2 L2 L2正则化超参数 λ \lambda λ的值。

9. 归一化输入 (Normalizing inputs)

训练神经网络时,其中一个加速训练的方法就是归一化输入

9.1 如何进行归一化?

假设一个训练集有两个特征 X = [ x 1 x 2 ] X=\begin{bmatrix} x1\\ x2\\ \end{bmatrix} X=[x1x2],即输入特征为2维。
在这里插入图片描述

归一化输入需要两个步骤:
第一步是零均值化,数学期望向量 μ \mu μ满足公式 μ = 1 m ∑ i = 1 m x ( i ) \mu=\frac1m\sum_{i=1}^mx^{(i)} μ=m1i=1mx(i),向量 X X X等于每个训练数据 x x x减去 μ \mu μ,即 x = x − μ x=x-\mu x=xμ,它的意思是移动训练集,直到它完成零均值化(如下图)。
在这里插入图片描述

第二步是归一化方差,注意上图,特征 x 1 x_1 x1的方差比特征 x 2 x_2 x2的方差要大得多,我们要做的是给 σ \sigma σ赋值,方差向量 σ 2 \sigma^2 σ2满足公式 σ 2 = 1 m ∑ i = 1 m ( x ( i ) ) 2 \sigma^2=\frac1m\sum_{i=1}^m(x^{(i)})^2 σ2=m1i=1m(x(i))2,它的每个特征都有方差,我们把所有数据除以向量 σ 2 \sigma^2 σ2 x 1 x_1 x1 x 2 x_2 x2的方差都等于1。
在这里插入图片描述

如果你用这组 μ \mu μ σ 2 \sigma^2 σ2来调整训练数据,那么也要用相同的 μ \mu μKaTeX parse error: Can't use function '\^' in math mode at position 1: \̲^̲来归一化测试集。我们希望无论是训练集和测试集都是通过相同的 μ \mu μ σ 2 \sigma^2 σ2定义的数据转换,其中 μ \mu μ σ 2 \sigma^2 σ2是由训练集得出来的。

9.2 为什么要归一化?

首先回顾一下代价函数: J ( w , b ) = 1 m ∑ i m L ( y ^ ( i ) , y ( i ) ) J(w,b)=\frac1m\sum_i^mL(\hat{y}^{(i)},y^{(i)}) J(w,b)=m1imL(y^(i),y(i))如果使用非归一化的输入特征,代价函数会像下图这样。
在这里插入图片描述

在多维环境下,这是一个非常细长狭窄的代价函数。如果画出该函数的部分轮廓,它会是这样一个狭长的函数。
在这里插入图片描述

假设特征 x 1 x_1 x1的取值范围从1到1000,特征 x 2 x_2 x2的取值范围从0到1,结果是参数 x 1 x_1 x1 x 2 x_2 x2值的范围或比率将会非常不同,这对优化算法非常不利。如果你在上图这样的代价函数上运行梯度下降法,你必须使用一个非常小的学习率(Learning rate)。因为如果是在这个位置(如下图),梯度下降法可能需要多次迭代过程,直到最后找到最小值。
在这里插入图片描述

但是如果使用归一化特征,代价函数看起来会更对称。
在这里插入图片描述

如果函数是一个更圆的球形轮廓,那么不论从哪个位置开始,梯度下降法都能够更直接地找到最小值。你可以在梯度下降法中使用较大步长,而不需要像非归一化中那样反复执行。
在这里插入图片描述

假设特征 x 1 x_1 x1取值范围在0到1之间,特征 x 2 x_2 x2取值范围在-1到1之间,因为它们是相似范围,所以会表现得很好。
实际上 w w w是一个高维向量,因此用二维绘制 w w w并不能正确地传达并直观理解,但总体上给我们的直观理解是代价函数会更圆一些,而且更容易优化。

10. 梯度消失与梯度爆炸 (Vanishing/Expanding Gradients)

训练神经网络,尤其是深度神经网络所面临的一个问题就是梯度消失或梯度爆炸,也就是在训练神经网络的时候,导数或坡度有时会变得非常大,或者非常小,甚至于以指数形式变小,这加大了训练的难度。
在这里插入图片描述

假设训练上图这样一个极深的神经网络,我们使用激活函数 g ( z ) = z g(z)=z g(z)=z,也就是线性激活函数,忽略 b b b,即 b [ l ] = 0 b^{[l]}=0 b[l]=0,那么根据如下推导: Z [ 1 ] = W [ 1 ] X Z^{[1]}=W^{[1]}X Z[1]=W[1]X A [ 1 ] = g [ 1 ] ( Z [ 1 ] ) = W [ 1 ] X A^{[1]}=g^{[1]}(Z^{[1]})=W^{[1]}X A[1]=g[1](Z[1])=W[1]X Z [ 2 ] = W [ 2 ] A [ 1 ] Z^{[2]}=W^{[2]}A^{[1]} Z[2]=W[2]A[1] A [ 2 ] = g [ 2 ] ( Z [ 2 ] ) = W [ 2 ] A [ 1 ] = W [ 2 ] W [ 1 ] X A^{[2]}=g^{[2]}(Z^{[2]})=W^{[2]}A^{[1]}=W^{[2]}W^{[1]}X A[2]=g[2](Z[2])=W[2]A[1]=W[2]W[1]X ⋯ \cdots 最终可以得到 y ^ = W [ L ] W [ L − 1 ] W [ L − 2 ] ⋯ W [ 2 ] W [ 1 ] X \hat{y}=W^{[L]}W^{[L-1]}W^{[L-2]}\cdots W^{[2]}W^{[1]}X y^=W[L]W[L1]W[L2]W[2]W[1]X 假设权重矩阵 W [ l ] = [ 1.5 0 0 1.5 ] W^{[l]}=\begin{bmatrix}1.5&0 \\0&1.5 \\ \end{bmatrix} W[l]=[1.5001.5],从技术上来讲,最后一项 W [ L ] W^{[L]} W[L]通常有不同维度,因此忽略这一项,从而可以得到 y ^ = W [ L ] [ 1.5 0 0 1.5 ] ( L − 1 ) X \hat{y}=W^{[L]}\begin{bmatrix}1.5&0 \\0&1.5 \\ \end{bmatrix}^{(L-1)}X y^=W[L][1.5001.5](L1)X假设所有权重矩阵都等于 [ 1.5 0 0 1.5 ] \begin{bmatrix}1.5&0 \\0&1.5 \\ \end{bmatrix} [1.5001.5],它是1.5倍的单位矩阵,也就是说 y ^ = 1. 5 L X \hat{y}=1.5^{L}X y^=1.5LX 如果对于一个深度神经网络来说, L L L值较大,那么 y ^ \hat{y} y^的值也会非常大,它会呈指数级增长,增长比率是 1. 5 L 1.5^L 1.5L
如果权重是0.5,即 W [ l ] = [ 0.5 0 0 0.5 ] W^{[l]}=\begin{bmatrix}0.5&0 \\0&0.5 \\ \end{bmatrix} W[l]=[0.5000.5],那么 y ^ = 0. 5 L X \hat{y}=0.5^{L}X y^=0.5LX每个矩阵都小于1,假设 x 1 x_1 x1 x 2 x_2 x2都是1,激活函数 a [ l ] a^{[l]} a[l]将变成 1 2 \frac12 21 1 4 \frac14 41 1 8 \frac18 81 ⋯ \cdots ,直到最后一项 1 2 L \frac1{2^L} 2L1。激活函数与网络层数 L L L相关,因此在深度网络中,激活函数的值将以指数级递减。
这里可以得到的直观理解是,若权重 w w w只比1略大一点,或略小一点,深度神经网络的激活函数都将爆炸式增长或递减。
这里虽然只讨论了激活函数以与层数 L L L相关的指数级增长或下降,但它也适用于与层数 L L L相关的导数或梯度函数,同样也是呈指数级增长或递减。

11. 神经网络的权重初始化 (Weight Initialization for Deep Networks)

在这里插入图片描述

首先从单个神经元入手,单个神经元可能有4个输入特征,从 x 1 x_1 x1 x 4 x_4 x4,经过 a = g ( z ) a=g(z) a=g(z)处理,最终得到 y ^ \hat{y} y^
这里 z z z可以写成如下的表达式(忽略 b b b): z = w 1 x 1 + w 2 x 2 + ⋯ + w n x n z=w_1x_1+w_2x_2+\cdots +w_nx_n z=w1x1+w2x2++wnxn为了预防 z z z值过大或过小,如果 n n n越大,即输入项越多,那么你会希望 w i w_i wi越小,因为 z z z w i x i w_ix_i wixi的和。如果把 w i x i w_ix_i wixi此类项相加,要想每一项的值更小,最合理的方法就是设置 w i w_i wi的样本方差为 1 n \frac1n n1,其中 n n n表示神经元的输入特征数量。
你所需要做的就是按照如下方式设置第 l l l层的权重矩阵 W [ l ] W^{[l]} W[l],其中n_(l-1)表示第 l − 1 l-1 l1层神经元的数量。

W_l = np.random.rand(shape) * np.sqrt(1/n_(l-1))

如果你用的激活函数是ReLu函数,那么方差设置为 2 n \frac2n n2,效果会更好。如果用tanh函数作为激活函数,方差设置为 1 n [ l − 1 ] \frac1{n^{[l-1]}} n[l1]1 2 n [ l − 1 ] + n [ l ] \frac{2}{n^{[l-1]}+n^{[l]}} n[l1]+n[l]2,则效果最好。
如果将激活函数的输入特征归一化,此时方差为1, z z z也会调整到相似范围,这样就没解决问题(梯度消失和梯度爆炸问题),但它确实降低了梯度消失和爆炸问题,因为它给权重矩阵 W W W设置了合理值。
实际上,上面这些公式只是给出初始化权重矩阵的方差的默认值。如果你需要添加方差,方差参数则是另一个你需要调整的超参数。实际做法可以给上面的公式乘上一个参数,虽然调优该参数能起到一定作用,但考虑到相比于其它超参数的重要性,通常把它的优先级放得比较低。

12. 梯度的数值逼近 (Numerical Approximation of Gradients)

在实施反向传播(backprop)时,有一个测试叫做梯度检验,它的作用是确保反向传播(backprop)正确实施。为了逐渐实现梯度检验,我们首先说说如何计算梯度的数值逼近。
在这里插入图片描述

以函数 f ( θ ) = θ 3 f(\theta)=\theta^3 f(θ)=θ3为例,假设 θ = 1 \theta=1 θ=1,不增大 θ \theta θ的值,而是在 θ \theta θ右侧设置 θ + ϵ \theta+\epsilon θ+ϵ,在 θ \theta θ左侧设置 θ − ϵ \theta-\epsilon θϵ ϵ \epsilon ϵ的值取0.01,因此 θ = 1 \theta=1 θ=1 θ + ϵ = 1.01 \theta+\epsilon=1.01 θ+ϵ=1.01 θ − ϵ = 0.99 \theta-\epsilon=0.99 θϵ=0.99
在这里插入图片描述

对于上面一个绿色三角形,上边的点对应的值是 f ( θ + ϵ ) f(\theta+\epsilon) f(θ+ϵ),下边的点是 f ( θ ) f(\theta) f(θ),因此这个三角形的高度是 f ( θ + ϵ ) − f ( θ ) f(\theta+\epsilon)-f(\theta) f(θ+ϵ)f(θ),下边的宽度是 ϵ \epsilon ϵ,高宽比为 f ( θ + ϵ ) − f ( θ ) ϵ \frac{f(\theta+\epsilon)-f(\theta)}{\epsilon} ϵf(θ+ϵ)f(θ)。导入具体参数,可以得到 f ( θ + ϵ ) − f ( θ − ϵ ) 2 ϵ = ( 1.01 ) 3 − ( 1.0 ) 3 0.01 = 3.0301 \frac{f(\theta+\epsilon)-f(\theta-\epsilon)}{2\epsilon}=\frac{(1.01)^3-(1.0)^3}{0.01}=3.0301 2ϵf(θ+ϵ)f(θϵ)=0.01(1.01)3(1.0)3=3.0301。当 θ = 1 \theta=1 θ=1时, g ( θ ) = 3 × θ 2 = 3 g(\theta)=3\times \theta^2=3 g(θ)=3×θ2=3,则逼近误差为0.0301。对于单边误差的计算,它的逼近误差可以写成 O ( ϵ ) O(\epsilon) O(ϵ) ϵ \epsilon ϵ值非常小,如果 ϵ = 0.01 \epsilon=0.01 ϵ=0.01 O ( ϵ ) = 0.0301 O(\epsilon)=0.0301 O(ϵ)=0.0301
在这里插入图片描述

对于上图中大一点的绿色三角形,上边的点对应的值是 f ( θ + ϵ ) f(\theta+\epsilon) f(θ+ϵ),下边的点是 f ( θ − ϵ ) f(\theta-\epsilon) f(θϵ),因此这个三角形的高度是 f ( θ + ϵ ) − f ( θ − ϵ ) f(\theta+\epsilon)-f(\theta-\epsilon) f(θ+ϵ)f(θϵ),下边的宽度是 2 ϵ 2\epsilon 2ϵ,高宽比为 f ( θ + ϵ ) − f ( θ − ϵ ) 2 ϵ \frac{f(\theta+\epsilon)-f(\theta-\epsilon)}{2\epsilon} 2ϵf(θ+ϵ)f(θϵ)。它的期望值接近 g ( θ ) g(\theta) g(θ),导入具体参数,可以得到 f ( θ + ϵ ) − f ( θ − ϵ ) 2 ϵ = ( 1.01 ) 3 − ( 0.99 ) 3 2 ∗ 0.01 = 3.0001 \frac{f(\theta+\epsilon)-f(\theta-\epsilon)}{2\epsilon}=\frac{(1.01)^3-(0.99)^3}{2*0.01}=3.0001 2ϵf(θ+ϵ)f(θϵ)=20.01(1.01)3(0.99)3=3.0001,当 θ = 1 \theta=1 θ=1时, g ( θ ) = 3 θ 2 = 3 g(\theta)=3\theta^2=3 g(θ)=3θ2=3,逼近误差为0.0001。对于一个非零的 ϵ \epsilon ϵ,它的逼近误差可以写成 O ( ϵ 2 ) O(\epsilon^2) O(ϵ2) ϵ \epsilon ϵ值非常小,如果 ϵ = 0.01 \epsilon=0.01 ϵ=0.01 O ( ϵ 2 ) = 0.0001 O(\epsilon^2)=0.0001 O(ϵ2)=0.0001
总体来说,使用双边误差的方法更逼近导数,且与运行两次单边误差的速度一样,其结果更接近于3。

13. 梯度检验 (Gradient Checking)

为了执行梯度检验,首先要做的就是把反向传播(backprop)中涉及到的所有 W W W矩阵转换成向量,之后再做连接运算,从而得到一个大的向量 θ \theta θ。因为代价函数 J J J是所有 W W W b b b的函数,所以你得到了一个参数 θ \theta θ的代价函数 J J J,即:
J ( W [ 1 ] , b [ 1 ] , ⋯   , W [ L ] , b [ L ] ) = J ( θ ) J(W^{[1]},b^{[1]},\cdots ,W^{[L]},b^{[L]})=J(\theta) J(W[1],b[1],,W[L],b[L])=J(θ)同样的,可以把 d W [ 1 ] dW^{[1]} dW[1] d b [ 1 ] db^{[1]} db[1] ⋯ ⋯ \cdots \cdots d W [ L ] dW^{[L]} dW[L] d b [ L ] db^{[L]} db[L]转换成一个新的大向量 d θ d\theta dθ,它与 θ \theta θ具有相同维度。
这就是实施梯度检验的过程,那么 d θ d\theta dθ和代价函数 J J J的梯度或坡度有什么关系呢?
首先,我们要清楚现在的代价函数 J ( θ ) J(\theta) J(θ)是超参数 θ \theta θ的一个函数,因此可以将函数 J J J展开成 J ( θ 1 , θ 2 , θ 3 , ⋯   ) J(\theta_1,\theta_2,\theta_3,\cdots) J(θ1,θ2,θ3,),无论超参数向量 θ \theta θ的维度是多少,为了实施梯度检验,你要做的就是循环执行,对每个 θ \theta θ组成元素计算 d θ a p p r o x [ i ] d\theta_{approx}[i] dθapprox[i]的值,由于使用的是双边误差,也就是 d θ a p p r o x [ i ] = J ( θ 1 , θ 2 , θ 3 , ⋯   , θ i + ϵ , ⋯   ) − J ( θ 1 , θ 2 , θ 3 , ⋯   , θ i − ϵ , ⋯   ) 2 ϵ d\theta_{approx}[i]=\frac{J(\theta_1,\theta_2,\theta_3,\cdots,\theta_i+\epsilon,\cdots)-J(\theta_1,\theta_2,\theta_3,\cdots,\theta_i-\epsilon,\cdots)}{2\epsilon} dθapprox[i]=2ϵJ(θ1,θ2,θ3,,θi+ϵ,)J(θ1,θ2,θ3,,θiϵ,) θ \theta θ的其它项全都保持不变。 d θ a p p r o x [ i ] d\theta_{approx}[i] dθapprox[i]应该逼近 d θ [ i ] = ∂ J ∂ θ i d\theta[i]=\frac{\partial J}{\partial \theta_i} dθ[i]=θiJ,其中 d θ [ i ] d\theta[i] dθ[i]是代价函数 J J J的偏导数。然后你需要对每个 θ \theta θ都执行这个运算,最后得到两个向量,分别是 d θ d\theta dθ d θ d\theta dθ的逼近值 d θ a p p r o x d\theta_{approx} dθapprox,它们两个具有相同维度,且与 θ \theta θ具有相同维度。
计算这两个向量的误差,可以使用这两者之差的欧几里得范数 ∣ ∣ d θ a p p r o x − d θ ∣ ∣ 2 ||d\theta_{approx}-d\theta||_2 dθapproxdθ2。注意这里 ∣ ∣ d θ a p p r o x − d θ ∣ ∣ 2 ||d\theta_{approx}-d\theta||_2 dθapproxdθ2没有平方,它的计算方式是误差平方之和,然后求平方根。最后用向量长度归一化,使用向量长度的欧几里得范数。 d i f f e r e n c e = ∣ ∣ d θ a p p r o x − d θ ∣ ∣ 2 ∣ ∣ d θ a p p r o x ∣ ∣ 2 + ∣ ∣ d θ ∣ ∣ 2 difference=\frac{||d\theta_{approx}-d\theta||_2}{||d\theta_{approx}||_2+||d\theta||_2} difference=dθapprox2+dθ2dθapproxdθ2 分母只是用于预防这些向量太小或太大,分母使得这个方程式变成比率。
如果你发现计算这个方程式得到的误差值为 1 0 − 7 10^{-7} 107或更小,这就意味着导数逼近很有可能是正确的,它的值非常小。
如果误差值在 1 0 − 5 10^{-5} 105范围内,那么可能这个值没问题,但我还是会再次检查这个向量的所有项,确保没有一项误差过大。
如果计算结果比 1 0 − 3 10^{-3} 103大很多,那么我就会很担心是否存在Bug。这时应该仔细检查所有 θ \theta θ项,看是否有一个具体的 θ i \theta_i θi值,使得 d θ a p p p r o x [ i ] d\theta_{appprox}[i] dθappprox[i] d θ [ i ] d\theta[i] dθ[i]大不相同,并用它来追踪一些求导计算是否正确。最终经过反复调试,最终结果会是这种非常小的值 1 0 − 7 10^{-7} 107

14. 梯度检验应用的注意事项 (Gradient Checking Implementation Notes)

在这里插入图片描述

  1. 不要在训练中使用梯度检验,它只用于调试。计算所有的 d θ a p p r o x [ i ] d\theta_{approx}[i] dθapprox[i]是一个非常漫长的计算过程,为了实施梯度下降,你必须使用 w w w b b b来计算 d θ d\theta dθ,并使用反向传播(backprop)来计算导数。只有在调试的时候,你才会计算它,来确认数值是否接近 d θ d\theta dθ。完成后,关闭梯度检验。梯度检验的每一个迭代过程都不执行它,因为它太慢了。
  2. 如果算法的梯度检验失败,要检查所有 θ \theta θ项,并试着找出Bug。也就是说,如果 d θ a p p r o x [ i ] d\theta_{approx}[i] dθapprox[i] d θ [ i ] dθ[i] dθ[i]的值相差很大,我们要做的就是查找不同的 θ i \theta_i θi值,看看是哪一项导致 d θ a p p r o x [ i ] d\theta_{approx}[i] dθapprox[i] d θ [ i ] d\theta[i] dθ[i]的值相差这么多。
  3. 在实施梯度检验时,如果使用正则化,请注意正则项。如果代价函数 J J J定义为 J ( θ ) = 1 m ∑ L ( y ^ ( i ) , y ( i ) ) + λ 2 m ∑ ∣ ∣ w [ l ] ∣ ∣ 2 J(\theta)=\frac1m\sum L(\hat{y}^{(i)},y^{(i)})+\frac{\lambda}{2m}\sum||w^{[l]}||^2 J(θ)=m1L(y^(i),y(i))+2mλw[l]2 d θ d\theta dθ是与 θ \theta θ相关的函数 J ( θ ) J(\theta) J(θ)的梯度, d θ d\theta dθ的计算应当要包括这个正则项。
  4. 梯度检验不能与dropout同时使用,因为每次迭代过程中,dropout会随机消除隐藏层单元的不同子集,难以计算dropout在梯度下降上的代价函数 J J J。因此我建议关闭dropout,用梯度检验进行双重检查,在没有dropout的情况下,你的算法至少是正确的,然后再打开dropout。
  5. w w w b b b接近0时,梯度下降的实施是正确的,但是在运行梯度下降时, w w w b b b变得更大。可能只有在 w w w b b b接近0时,梯度下降的实施才是正确的。但是当 w w w b b b变大时,它会变得越来越不准确。你所需要做的就是在随机初始化过程中,运行梯度检验,然后再训练网络, w w w b b b会有一段时间远离0,如果随机初始化值比较小,反复训练网络之后,再重新运行梯度检验。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值