稀疏自动编码之梯度检验

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

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

egin{align}
	heta := 	heta - alpha frac{d}{d	heta}J(	heta).
end{align}

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

回忆导数的定义:

egin{align}
frac{d}{d	heta}J(	heta) = lim_{epsilon 
ightarrow 0}
frac{J(	heta+ epsilon) - J(	heta-epsilon)}{2 epsilon}.
end{align}

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

egin{align}
frac{J(	heta+{
m EPSILON}) - J(	heta-{
m EPSILON})}{2 	imes {
m EPSILON}}
end{align}

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

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

egin{align}
g(	heta) approx
frac{J(	heta+{
m EPSILON}) - J(	heta-{
m EPSILON})}{2 	imes {
m EPSILON}}.
end{align}

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

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

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

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

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

egin{align}
g_i(	heta) approx
frac{J(	heta^{(i+)}) - J(	heta^{(i-)})}{2 	imes {
m EPSILON}}.
end{align}

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

这展示在

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

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

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

原文地址:https://www.cnblogs.com/90zeng/p/Gradient_checking.html