稀疏自动编码之梯度检验

众所周知,反向传播算法很难调试和得到正确结果,特别是在执行过程中存在许多细小难以察觉的错误。这里介绍一种方法来确定代码中导数的计算是否正确。使用这里所述求导检验方法,可以帮助提升写正确代码的信心。

假设我们想最小化关于 \textstyle \theta 的函数 \textstyle J(\theta)  . 对于这个例子,假设 \textstyle J : \Re \mapsto \Re,所以 \textstyle \theta \in \Re. 在一维空间,梯度下降的一次迭代公式如下:

\begin{align}
\theta := \theta - \alpha \frac{d}{d\theta}J(\theta).
\end{align}

假设我们已经实现了某个函数 \textstyle g(\theta) 去计算 \textstyle \frac{d}{d\theta}J(\theta),那么梯度下降时参数更新就可以这样:\textstyle \theta := \theta - \alpha g(\theta). 该如何检验我们编写的函数 \textstyle g 是正确的呢?

回忆导数的定义:

\begin{align}
\frac{d}{d\theta}J(\theta) = \lim_{\epsilon \rightarrow 0}
\frac{J(\theta+ \epsilon) - J(\theta-\epsilon)}{2 \epsilon}.
\end{align}

对于任意的 \textstyle \theta ,可以用如下公式来从数值上近似导数值:

\begin{align}
\frac{J(\theta+{\rm EPSILON}) - J(\theta-{\rm EPSILON})}{2 \times {\rm EPSILON}}
\end{align}

在实践中,将  EPSILON 设定为一个极小的常数,如 \textstyle 10^{-4}.(虽然EPSILON可以取得极其小的值,如\textstyle 10^{-20},但这样会导致数值舍入误差),通常\textstyle 10^{-4}就足够了。

现在,给定假设中计算 \textstyle \frac{d}{d\theta}J(\theta) 的函数 \textstyle g(\theta) ,我们可以通过如下方式检验该函数的正确如否:

\begin{align}
g(\theta) \approx
\frac{J(\theta+{\rm EPSILON}) - J(\theta-{\rm EPSILON})}{2 \times {\rm EPSILON}}.
\end{align}

 

到底这两个值接近到什么样的一个程度才算正确呢?要取决于 \textstyle J 的具体形似。但是假定 \textstyle {\rm EPSILON} = 10^{-4}, 通常我们会发现上述式子左右两边的值至少有4位有效数字是一样的(甚至更多)。

现在,考虑 \textstyle \theta \in \Re^n,即参数是一个向量而不是一个实数(所以需要学习出 \textstyle n 个参数),且\textstyle J: \Re^n \mapsto \Re. 在我们的神经网络例子中使用符号\textstyle J(W,b), 所以我们可以想象把这许多参数 \textstyle W,b  全部装进一个很长的向量 \textstyle \theta. 现在,就把导数检验过程泛化到 \textstyle \theta 是向量的情况。

 

假设我们编写了一个函数 \textstyle g_i(\theta) 计算导数 \textstyle \frac{\partial}{\partial \theta_i} J(\theta),我们想要检验 \textstyle g_i 是否正确地计算出了导数值. 令\textstyle \theta^{(i+)} = \theta +
{\rm EPSILON} \times \vec{e}_i,其中:

\begin{align}
\vec{e}_i = \begin{bmatrix}0 \\ 0 \\ \vdots \\ 1 \\ \vdots \\ 0\end{bmatrix}
\end{align}

是第 \textstyle i 个基向量(维数与 \textstyle \theta 一样,只有第 \textstyle i 个元素为1,其他位置元素全部为0).所以对于 \textstyle \theta^{(i+)},除了第 \textstyle i 个元素比\textstyle \theta的第 \textstyle i 个元素多加了EPSILON,其他元素完全一样。类似地有:\textstyle \theta^{(i-)} = \theta - {\rm EPSILON} \times \vec{e}_i.然后就可以通过检查下面式子的正确与否来检验 \textstyle g_i(\theta) 的正确性:

\begin{align}
g_i(\theta) \approx
\frac{J(\theta^{(i+)}) - J(\theta^{(i-)})}{2 \times {\rm EPSILON}}.
\end{align}

 当用反向传播去训练神经网络时, 正确执行的算法可以得到:

这展示在

稀疏自动编码之反向传播算法(BP)

的梯度下降伪代码中.通常用上面的方法计算出 \textstyle J(W,b) 的导数值,通过它检验我们程序中 \textstyle \left(\frac{1}{m}\Delta W^{(l)} \right) + \lambda W 和 \textstyle \frac{1}{m}\Delta b^{(l)} 是否确实计算出了我们想要的到数值。

 

 学习来源:http://deeplearning.stanford.edu/wiki/index.php/Gradient_checking_and_advanced_optimization

 

posted @ 2014-10-13 10:10  90Zeng  阅读(1092)  评论(0编辑  收藏  举报