梯度检测主要是用来验证反向传播算法是否是正确的,其主要步骤如下:
使用反向传播算法计算 D V e c DVec DVec(各层误差项的展开形式)使用数值梯度检测计算近似梯度将得到的两个值(向量)进行对比,确保二者相似
如果二者相似的话说明反向传播算法实现无误,这时候需要关闭梯度检测,然后使用反向传播的代码进行学习如果二者差别较大则说明反向传播算法实现有误,需要对其进行改正,改正完后再次进行对比
重点!!!确保在训练前关闭了梯度检测,如果没有关闭的话,那么会在每个内循环都运行,你的训练速度会非常非常慢,梯度检测算法比反向传播算法慢的多
接下来说一下怎样计算近似梯度。
近似梯度的计算使用了高等数学中逼近的思想,计算一点的导数可以取其临近两点的斜率代替,如果这两点足够近,那么就可以使用这个斜率代替该点导数。
这种方式叫做双侧差分(two-sided difference),具体的计算公式如下:
d d θ J ( θ ) ≈ J ( θ + ϵ ) − J ( θ − ϵ ) 2 ϵ frac{d}{dtheta} J(theta) approx frac{J(theta+epsilon)-J(theta-epsilon)}{2epsilon} dθdJ(θ)≈2ϵJ(θ+ϵ)−J(θ−ϵ)
一般情况下会取 ϵ = 1 0 − 4 epsilon = 10^{-4} ϵ=10−4
还有另外一种实现方式,叫做单侧差分,实现公式如下:
d d θ J ( θ ) ≈ J ( θ + ϵ ) − J ( θ ) ϵ frac{d}{dtheta} J(theta) approx frac{J(theta+epsilon)-J(theta)}{epsilon} dθdJ(θ)≈ϵJ(θ+ϵ)−J(θ)
双侧差分可以得到更加准确的结果,因此一般不使用这种方式
在上面的情况中只考虑了 θ theta θ是一个实数的情况,当 θ theta θ是一个向量的时候也是类似的。
θ ∈ R n , θ = θ 1 , θ 2 , . . . , θ n theta in R ^n,theta = theta_1,theta_2,...,theta_n θ∈Rn,θ=θ1,θ2,...,θn
我们可以通过下面这些公式计算代价函数关于不同参数的近似梯度
通过上述公式我们可以计算 J J J关于任何参数的偏导数
代码实现如下:
for i in range(n): theta_plus = theta theta_plus[i] = theta_plus[i] + EPSILON theta_minus = theta theta_minus[i] = theta_minus[i] + EPSILON grad_approx[i] = (J(theta_plus) - J(theta_minus)) / (2 * EPSILON)
最后只需要比较grad_approx和使用反向传播算法计算得到的误差即可