【深度学习基础】第十四课:梯度检验

梯度的数值逼近,梯度检验

Posted by x-jeff on February 12, 2020

【深度学习基础】系列博客为学习Coursera上吴恩达深度学习课程所做的课程笔记。
本文为原创文章,未经本人允许,禁止转载。转载请注明出处。

1.前言

梯度检验(gradient checking)的作用是确保反向传播的正确实施。

为了逐渐实现梯度检验,我们首先了解下如何对梯度做数值逼近。

2.梯度的数值逼近

假设我们有函数$f(\theta)=\theta ^3$,图像见下:

如图所示,假设我们考虑$\theta=1$时的导数并且有一个很小的值$\epsilon=0.01$。

如果使用单边误差估计导数

\[\frac{f(\theta+\epsilon)-f(\theta)}{\epsilon}=\frac{1.01^3-1}{0.01}=3.0301\]

如果使用双边误差估计导数

\[\frac{f(\theta+\epsilon)-f(\theta-\epsilon)}{2\epsilon}=\frac{1.01^3-0.99^3}{2\times 0.01}=3.0001\]

$\theta=1$时,函数的导数为:

\[f'(\theta)=3\theta ^2=3\]

很明显,双边误差对导数的估计更加准确。这是因为单边估计时误差为$O(\epsilon)$,而双边估计时误差为$O(\epsilon ^2)$,当$\epsilon <1$时,肯定有$\epsilon ^2 < \epsilon$,因此双边估计比单边估计更为准确。

⚠️我们在做梯度检验时就会用到双边误差公式。

3.梯度检验

把神经网络的所有参数:$W^{[1]},b^{[1]},…,W^{[L]},b^{[L]}$合成一个大的向量$\theta$。

同样的,把$dW^{[1]},db^{[1]},…,dW^{[L]},db^{[L]}$也合成一个大的向量$d\theta$。

其中,$\theta$和$d\theta$的维度是完全一样的。

cost function为:

\[J(W^{[1]},b^{[1]},...,W^{[L]},b^{[L]})=J(\theta_1,\theta_2,...)=J(\theta)\]

利用第2部分介绍的双边误差公式,计算每一个$\theta_i$的导数近似值:

\[d\theta_{approx}[i]=\frac{J(\theta_1,\theta_2,...,\theta_i+\epsilon,...)-J(\theta_1,\theta_2,...,\theta_i-\epsilon,...)}{2\epsilon}\]

如果后向传播正确的话,我们得到的$d\theta_{approx}[i]$应该是接近于$d\theta [i]$的。总体看来,也就是两个大的向量:$d\theta_{approx}$和$d\theta$之间应该是接近的。

采用以下公式计算$d\theta_{approx}$和$d\theta$之间的接近程度:

\[\frac{\parallel d\theta_{approx} - d\theta \parallel _2}{\parallel d\theta_{approx} \parallel _2+\parallel d\theta \parallel _2} \approx \epsilon\]

其实就是计算欧式距离并做了归一化处理。通常$\epsilon = 10^{-7}$。如果计算得到的值远远大于$10^{-7}$,那很有可能就是反向传播的时候出现了错误。但这并不是绝对的,也有可能没有错误,这只是意味着出现错误的可能性很大。

4.梯度检验的实现技巧和注意事项

  • 不要在训练中使用梯度检验,它只用于调试。因为梯度检验的过程会很慢。
  • 如果算法的梯度检验失败,要检查每一项,试着找出bug。
  • 在实施梯度检验时,如果使用了正则化,一定要记着在计算时带上正则项。
  • 梯度检验不能与dropout同时使用。
  • 当W和b接近0时,梯度检验可能总是正确的。但是W和b非常接近0的情况很少见。

5.代码地址

  1. 深度学习的实用层面