吴恩达深度学习笔记:深度学习的 实践层面 (Practical aspects of Deep Learning)1.13-1.14

第二门课: 改善深层神经网络:超参数调试、正 则 化 以 及 优 化 (Improving Deep Neural Networks:Hyperparameter tuning, Regularization and Optimization)

第一周:深度学习的 实践层面 (Practical aspects of Deep Learning)

1.13 梯度检验(Gradient checking)

梯度检验帮我们节省了很多时间,也多次帮我发现 backprop 实施过程中的 bug,接下来,我们看看如何利用它来调试或检验 backprop 的实施是否正确。

假设你的网络中含有下列参数, W [ 1 ] W^{[1]} W[1] b [ 1 ] b^{[1]} b[1]…… W [ l ] W^{[l]} W[l] b [ l ] b^{[l]} b[l],为了执行梯度检验,首先要做的就是,把所有参数转换成一个巨大的向量数据,你要做的就是把矩阵𝑊转换成一个向量,把所有𝑊矩阵转换成向量之后,做连接运算,得到一个巨型向量𝜃,该向量表示为参数𝜃,代价函数𝐽是所有𝑊和𝑏的函数,现在你得到了一个𝜃的代价函数𝐽(即𝐽(𝜃))。接着,你得到与𝑊和𝑏顺序相同的数据,你同样可以把 d W [ 1 ] dW^{[1]} dW[1] d b [ 1 ] db^{[1]} db[1]…… d W [ l ] dW^{[l]} dW[l] d b [ l ] db^{[l]} db[l]转换成一个新的向量,用它们来初始化大向量𝑑𝜃,它与𝜃具有相同维度。

同样的,把 d W [ 1 ] dW^{[1]} dW[1]转换成矩阵, d b [ 1 ] db^{[1]} db[1]已经是一个向量了,直到把 d W [ l ] dW^{[l]} dW[l]转换成矩阵,这样所有的𝑑𝑊都已经是矩阵,注意 d W [ 1 ] dW^{[1]} dW[1] W [ 1 ] W^{[1]} W[1]具有相同维度, d b [ 1 ] db^{[1]} db[1] b [ 1 ] b^{[1]} b[1]具有相同维度。经过相同的转换和连接运算操作之后,你可以把所有导数转换成一个大向量𝑑𝜃,它与𝜃具有相同维度,现在的问题是𝑑𝜃和代价函数𝐽的梯度或坡度有什么关系?
在这里插入图片描述
这就是实施梯度检验的过程,英语里通常简称为“grad check”,首先,我们要清楚𝐽是超参数𝜃的一个函数,你也可以将𝐽函数展开为𝐽(𝜃1, 𝜃2, 𝜃3, … … ),不论超级参数向量𝜃的维度是多少,为了实施梯度检验,你要做的就是循环执行,从而对每个𝑖也就是对每个𝜃组成元素计算𝑑𝜃approx[𝑖]的值,我使用双边误差,也就是
d θ a p p r o x [ i ] = J ( θ 1 , θ 2 , . . . . . . θ i + ε , . . . ) − J ( θ 1 , θ 2 , . . . . . . θ i − ε , . . . ) 2 ε dθ_{approx}[i] =\frac{J(θ_1,θ_2,......θ_i+ε,...) - J(θ_1,θ_2,......θ_i-ε,...)}{2ε} dθapprox[i]=2εJ(θ1,θ2,......θi+ε,...)J(θ1,θ2,......θiε,...)

只对 θ i θ_i θi增加𝜀,其它项保持不变,因为我们使用的是双边误差,对另一边做同样的操作,只不过是减去𝜀,𝜃其它项全都保持不变。
在这里插入图片描述
从上节课中我们了解到这个值( d θ a p p r o x [ i ] dθ_{approx}[i] dθapprox[i])应该逼近𝑑𝜃[𝑖]=𝜕𝐽/𝜕𝜃𝑖,𝑑𝜃[𝑖]是代价函数的偏导数,然后你需要对𝑖的每个值都执行这个运算,最后得到两个向量,得到𝑑𝜃的逼近值 d θ a p p r o x dθ_{approx} dθapprox,它与𝑑𝜃具有相同维度,它们两个与𝜃具有相同维度,你要做的就是验证这些向量是否彼此接近。

具体来说,如何定义两个向量是否真的接近彼此?我一般做下列运算,计算这两个向量的距离,𝑑𝜃approx[𝑖] − 𝑑𝜃[𝑖]的欧几里得范数,注意这里(||𝑑𝜃approx − 𝑑𝜃||2)没有平方,它是误差平方之和,然后求平方根,得到欧式距离,然后用向量长度归一化,使用向量长度的欧几里得范数。分母只是用于预防这些向量太小或太大,分母使得这个方程式变成比率,我们实际执行这个方程式,𝜀可能为 1 0 − 7 10^{−7} 107,使用这个取值范围内的𝜀,如果你发现计算方程式得到的值为 1 0 − 7 10^{−7} 107或更小,这就很好,这就意味着导数逼近很有可能是正确的,它的值非常小。

在这里插入图片描述
如果它的值在 1 0 − 5 10^{−5} 105范围内,我就要小心了,也许这个值没问题,但我会再次检查这个向量的所有项,确保没有一项误差过大,可能这里有 bug。

如果左边这个方程式结果是 1 0 − 3 10^{−3} 103,我就会担心是否存在 bug,计算结果应该比 1 0 − 3 10^{−3} 103小很多,如果比 1 0 − 3 10^{−3} 103大很多,我就会很担心,担心是否存在 bug。这时应该仔细检查所有𝜃项,看是否有一个具体的𝑖值,使得𝑑𝜃approx[𝑖]与𝑑𝜃[𝑖]大不相同,并用它来追踪一些求导计算是否正确,经过一些调试,最终结果会是这种非常小的值( 1 0 − 7 10^{−7} 107),那么,你的实施可能是正确的。

在这里插入图片描述
在实施神经网络时,我经常需要执行 foreprop 和 backprop,然后我可能发现这个梯度检验有一个相对较大的值,我会怀疑存在 bug,然后开始调试,调试,调试,调试一段时间后,我得到一个很小的梯度检验值,现在我可以很自信的说,神经网络实施是正确的。

现在你已经了解了梯度检验的工作原理,它帮助我在神经网络实施中发现了很多 bug,希望它对你也有所帮助。

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

这节课,分享一些关于如何在神经网络实施梯度检验的实用技巧和注意事项。

在这里插入图片描述
首先,不要在训练中使用梯度检验,它只用于调试。我的意思是,计算所有𝑖值的 d θ a p p r o x [ i ] dθ_{approx}[i] dθapprox[i]是一个非常漫长的计算过程,为了实施梯度下降,你必须使用𝑊和𝑏 backprop 来计算𝑑𝜃,并使用 backprop 来计算导数,只要调试的时候,你才会计算它,来确认数值是否接近𝑑𝜃。完成后,你会关闭梯度检验,梯度检验的每一个迭代过程都不执行它,因为它太慢了。

第二点,如果算法的梯度检验失败,要检查所有项,检查每一项,并试着找出 bug,也就是说,如果 d θ a p p r o x [ i ] dθ_{approx}[i] dθapprox[i]与𝑑𝜃[𝑖]的值相差很大,我们要做的就是查找不同的𝑖值,看看是哪个导致 d θ a p p r o x [ i ] dθ_{approx}[i] dθapprox[i]与𝑑𝜃[𝑖]的值相差这么多。举个例子,如果你发现,相对某些层或某层的𝜃或𝑑𝜃的值相差很大,但是dw[𝑙]的各项非常接近,注意𝜃的各项与𝑏和𝑤的各项都是一一对应的,这时,你可能会发现,在计算参数𝑏的导数𝑑𝑏的过程中存在 bug。反过来也是一样,如果你发现它们的值相差很大, d θ a p p r o x [ i ] dθ_{approx}[i] dθapprox[i]的值与𝑑𝜃[𝑖]的值相差很大,你会发现所有这些项目都来自于𝑑𝑤或某层的𝑑𝑤,可能帮你定位 bug 的位置,虽然未必能够帮你准确定位 bug 的位置,但它可以帮助你估测需要在哪些地方追踪 bug。

第三点,在实施梯度检验时,如果使用正则化,请注意正则项。如果代价函数 J ( θ ) = 1 m ∑ L ( y ^ ( i ) , y ( i ) ) + λ 2 m ∑ ∣ ∣ W [ l ] ∣ ∣ 2 J(θ) =\frac{1}{m}\sum{L(\hat{y}^{(i)},y^{(i)})} + \frac{λ}{2m}\sum||W^{[l]}||^2 J(θ)=m1L(y^(i),y(i))+2mλ∣∣W[l]2,这就是代价函数𝐽的定义,𝑑𝜃等于与𝜃相关的𝐽函数的梯度,包括这个正则项,记住一定要包括这个正则项。

第四点,梯度检验不能与 dropout 同时使用,因为每次迭代过程中,dropout 会随机消除隐藏层单元的不同子集,难以计算 dropout 在梯度下降上的代价函数𝐽。因此 dropout 可作为优化代价函数𝐽的一种方法,但是代价函数𝐽被定义为对所有指数极大的节点子集求和。而在任何迭代过程中,这些节点都有可能被消除,所以很难计算代价函数𝐽。你只是对成本函数做抽样,用dropout,每次随机消除不同的子集,所以很难用梯度检验来双重检验dropout的计算,所以我一般不同时使用梯度检验和 dropout。如果你想这样做,可以把 dropout 中的 keepprob 设置为 1.0,然后打开 dropout,并寄希望于 dropout 的实施是正确的,你还可以做点别的,比如修改节点丢失模式确定梯度检验是正确的。实际上,我一般不这么做,我建议关闭 dropout,用梯度检验进行双重检查,在没有 dropout 的情况下,你的算法至少是正确的,然后打开dropout。

最后一点,也是比较微妙的一点,现实中几乎不会出现这种情况。当𝑤和𝑏接近 0 时,梯度下降的实施是正确的,在随机初始化过中……,但是在运行梯度下降时,𝑤和𝑏变得更大。可能只有在𝑤和𝑏接近 0 时,backprop 的实施才是正确的。但是当𝑊和𝑏变大时,它会变得越来越不准确。你需要做一件事,我不经常这么做,就是在随机初始化过程中,运行梯度检验,然后再训练网络,𝑤和𝑏会有一段时间远离 0,如果随机初始化值比较小,反复训练网络之后,再重新运行梯度检验。

这就是梯度检验,恭喜大家,这是本周最后一课了。回顾这一周,我们讲了如何配置训练集,验证集和测试集,如何分析偏差和方差,如何处理高偏差或高方差以及高偏差和高方差并存的问题,如何在神经网络中应用不同形式的正则化,如𝐿2正则化和 dropout,还有加快神经网络训练速度的技巧,最后是梯度检验。这一周我们学习了很多内容,你可以在本周编程作业中多多练习这些概念。祝你好运,期待下周再见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值