梯度检测算法
梯度检测主要是用来验证反向传播算法是否是正确的,其主要步骤如下:
- 使用反向传播算法计算 D V e c DVec DVec(各层误差项的展开形式)
- 使用数值梯度检测计算近似梯度
- 将得到的两个值(向量)进行对比,确保二者相似
- 如果二者相似的话说明反向传播算法实现无误,这时候需要关闭梯度检测,然后使用反向传播的代码进行学习
- 如果二者差别较大则说明反向传播算法实现有误,需要对其进行改正,改正完后再次进行对比
重点!!!确保在训练前关闭了梯度检测,如果没有关闭的话,那么会在每个内循环都运行,你的训练速度会非常非常慢,梯度检测算法比反向传播算法慢的多
接下来说一下怎样计算近似梯度。
近似梯度的计算使用了高等数学中逼近的思想,计算一点的导数可以取其临近两点的斜率代替,如果这两点足够近,那么就可以使用这个斜率代替该点导数。
这种方式叫做双侧差分(two-sided difference),具体的计算公式如下:
d
d
θ
J
(
θ
)
≈
J
(
θ
+
ϵ
)
−
J
(
θ
−
ϵ
)
2
ϵ
\frac{d}{d\theta} J(\theta) \approx \frac{J(\theta+\epsilon)-J(\theta-\epsilon)}{2\epsilon}
dθdJ(θ)≈2ϵJ(θ+ϵ)−J(θ−ϵ)
一般情况下会取
ϵ
=
1
0
−
4
\epsilon = 10^{-4}
ϵ=10−4
还有另外一种实现方式,叫做单侧差分,实现公式如下:
d d θ J ( θ ) ≈ J ( θ + ϵ ) − J ( θ ) ϵ \frac{d}{d\theta} 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
和使用反向传播算法计算得到的误差即可